# API REST CAN

API RESTful escalable y segura construida con Symfony 8 y API Platform 4

## 📋 Tecnologías

- **PHP**: 8.2+
- **Symfony**: 8.1
- **API Platform**: 4.3
- **Doctrine ORM**: 3.6
- **JWT**: Autenticación con tokens JWT
- **MySQL**: Base de datos (compatible con MAMP)
- **CORS**: Configurado con Nelmio

## 🚀 Inicio Rápido

### Requisitos Previos

- PHP 8.2+
- Composer
- MySQL (MAMP)
- Symfony CLI (opcional)

### Instalación

```bash
# 1. Clonar o navegar al proyecto
cd /Applications/MAMP/htdocs/apirestcan

# 2. Instalar dependencias (ya instaladas)
composer install

# 3. Generar claves JWT (ya generadas)
php bin/console lexik:jwt:generate-keypair

# 4. Crear base de datos (ya creada)
php bin/console doctrine:database:create --if-not-exists

# 5. Ejecutar migraciones
php bin/console doctrine:migrations:migrate
```

### Iniciar Servidor

```bash
# Opción 1: Con Symfony CLI
symfony serve

# Opción 2: Con PHP nativo
php -S localhost:8000 -t public

# Opción 3: Con Apache (MAMP)
# Solo copia en /Applications/MAMP/htdocs/apirestcan y accede a http://localhost/apirestcan
```

## 📁 Estructura del Proyecto

```
src/
├── Application/        # Casos de uso, servicios de aplicación
├── Domain/            # Lógica de negocio encapsulada
│   ├── Entity/        # Entidades Doctrine
│   ├── ValueObject/   # Value Objects
│   └── Repository/    # Interfaces de repositorio
├── Infrastructure/    # Implementaciones Doctrine, eventos, servicios
├── Presentation/      # DTOs, Transformers
├── Services/          # Servicios inyectables
└── Controller/        # Controladores específicos
```

## 📚 Documentación de API

Una vez iniciado el servidor, accede a:

- **API Docs (Swagger UI)**: `http://localhost:8000/api/docs`
- **OpenAPI Schema**: `http://localhost:8000/api/openapi.json`
- **Entrypoint**: `http://localhost:8000/api/`

## 🔐 Autenticación JWT

### Generar Token

```bash
curl -X POST http://localhost:8000/api/login \
  -H "Content-Type: application/json" \
  -d '{"username":"user","password":"password"}'
```

Respuesta:
```json
{
  "token": "eyJ0eXAiOiJKV1QiLCJhbGc..."
}
```

### Usar Token

```bash
curl -H "Authorization: Bearer YOUR_TOKEN" \
  http://localhost:8000/api/recursos
```

## 🗄️ Configuración de Base de Datos

### MySQL (MAMP)

Archivo: `.env`

```
DATABASE_URL="mysql://root:root@127.0.0.1:3306/apirestcan?serverVersion=8.0.32&charset=utf8mb4"
```

- **Host**: 127.0.0.1
- **Port**: 3306 (por defecto MAMP)
- **Usuario**: root
- **Contraseña**: root
- **BD**: apirestcan

### Cambiar a PostgreSQL

```
DATABASE_URL="postgresql://app:!ChangeMe!@127.0.0.1:5432/app?serverVersion=16&charset=utf8"
```

## 🏗️ Crear un Recurso API

### 1. Crear Entidad

```bash
php bin/console make:entity Producto
```

### 2. Agregar atributo `#[ApiResource]`

```php
<?php
namespace App\Domain\Entity;

use ApiPlatform\Metadata\ApiResource;
use Doctrine\ORM\Mapping as ORM;

#[ApiResource]
#[ORM\Entity]
class Producto
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

    #[ORM\Column(length: 255)]
    private string $nombre;

    #[ORM\Column]
    private float $precio;

    // Getters y setters...
}
```

### 3. Crear Migración

```bash
php bin/console doctrine:make:migration
php bin/console doctrine:migrations:migrate
```

### 4. Acceder a la API

```
GET    /api/productos              # Listar
POST   /api/productos              # Crear
GET    /api/productos/{id}         # Ver
PUT    /api/productos/{id}         # Actualizar
DELETE /api/productos/{id}         # Eliminar
```

## 🔒 Seguridad y Autorización

### Voter (Control de Acceso)

```php
php bin/console make:voter ProductoVoter
```

### Aplicar Seguridad en Recurso

```php
#[Security("is_granted('create', object)")]
#[Post]
```

## 📝 Validación

### Constraints

```php
use Symfony\Component\Validator\Constraints as Assert;

#[ORM\Column(length: 255)]
#[Assert\NotBlank]
#[Assert\Length(min: 3, max: 255)]
private string $nombre;
```

## 🧪 Testing

```bash
# Ejecutar tests
php bin/phpunit

# Con cobertura
php bin/phpunit --coverage-html coverage/
```

## 📋 Comandos Útiles

```bash
# Limpiar caché
php bin/console cache:clear

# Listar rutas
php bin/console debug:router

# Validar esquema BD
php bin/console doctrine:schema:validate

# Generar DTOs
php bin/console make:entity --api-resource

# Ver estado de recipes
composer recipes
```

## 🛠️ Configuración Avanzada

### CORS

Archivo: `config/packages/nelmio_cors.yaml`

```yaml
nelmio_cors:
    defaults:
        origin_regex: true
        allow_origin: ['%env(CORS_ALLOW_ORIGIN)%']
        allow_methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE']
```

### Paginación

```php
#[ApiResource(
    operations: [
        new GetCollection(paginationItemsPerPage: 20)
    ]
)]
```

### Filtros

```bash
composer require api-platform/doctrine-orm
```

## 📦 Variables de Entorno

Configurar en `.env.local`:

```
APP_ENV=dev
APP_SECRET=your_secret
DATABASE_URL=mysql://...
JWT_SECRET_KEY=%kernel.project_dir%/config/jwt/private.pem
JWT_PUBLIC_KEY=%kernel.project_dir%/config/jwt/public.pem
JWT_PASSPHRASE=your_passphrase
CORS_ALLOW_ORIGIN=^https?://(localhost|127\.0\.0\.1)(:[0-9]+)?$
```

## 🚢 Deploy a Producción

```bash
# 1. Compilar variables de entorno
composer dump-env prod

# 2. Compilar caché
php bin/console cache:warmup --env=prod

# 3. Ejecutar migraciones
php bin/console doctrine:migrations:migrate --env=prod

# 4. Ejecutar con servidor seguro (HTTPS)
# Usar Apache con mod_rewrite o Nginx
```

## 📚 Referencias

- [API Platform Docs](https://api-platform.com/docs/)
- [Symfony Docs](https://symfony.com/doc/current/)
- [Doctrine ORM](https://www.doctrine-project.org/)
- [JWT.io](https://jwt.io/)

## 📄 Licencia

Este proyecto está bajo licencia MIT.

## 👨‍💻 Autor

Creado con ❤️ para APIs robustas y escalables.
