Saltar al contenido principal

Diseño de APIs

Esta guía establece los estándares para diseñar y construir APIs RESTful robustas, consistentes y fáciles de consumir desde cualquier cliente (frontend, móvil, servicios externos).


Principios de Diseño​

  1. Consistencia: Todas las APIs deben seguir las mismas convenciones de nomenclatura, estructura de respuesta y códigos de error.
  2. Descubribilidad: Los endpoints deben ser intuitivos. Un desarrollador debería poder adivinar la URL de un recurso.
  3. Versionado: Siempre incluir la versión en la ruta base (/api/v1/).

Base URL y Versionado​

Todos los endpoints deben usar el prefijo:

/api/v1/[recurso]

Ejemplos:

  • /api/v1/usuarios
  • /api/v1/productos
  • /api/v1/ordenes-de-compra

Nomenclatura de Endpoints​

  • Formato: kebab-case (minúsculas separadas por guiones).
  • Sustantivos en plural: Los recursos siempre deben ser nombrados en plural.
✅ Correcto❌ Incorrecto
/api/v1/usuarios/api/v1/usuario
/api/v1/ordenes-de-compra/api/v1/ordenDeCompra
/api/v1/tipos-de-producto/api/v1/product_types

Métodos HTTP Estándar​

MétodoPropósitoIdempotenteBody
GETRecuperar uno o más recursosSíNo
POSTCrear un nuevo recursoNoSí
PUTReemplazar un recurso completoSíSí
PATCHActualización parcial o acción específicaNoSí (opcional)
DELETEEliminar un recursoSíNo

Estructura de Endpoints CRUD​

Para un recurso [entidad], los endpoints estándar son:

1. Listar Recursos​

GET /api/v1/[entidad]/

Query Parameters Estándar:

ParámetroTipoDefaultDescripción
skipint0Registros a omitir (paginación).
limitint100Máximo de registros a retornar (max: 1000).
is_activebool(todos)Filtrar por estado activo/inactivo.
name_containsstring-Búsqueda parcial por nombre.
[entidad]_idsstring-IDs separados por comas (ej: 1,3,5).

Respuesta: Lista de DTOs de respuesta.

2. Obtener por ID​

GET /api/v1/[entidad]/{id}

Respuesta: DTO de respuesta o 404 Not Found.

3. Crear Recurso​

POST /api/v1/[entidad]/

Body: DTO de creación.
Respuesta: DTO de respuesta con el recurso creado.

4. Actualizar Recurso​

PUT /api/v1/[entidad]/{id}

Body: DTO de actualización.
Respuesta: DTO de respuesta con el recurso actualizado.

5. Eliminar Recurso​

DELETE /api/v1/[entidad]/{id}

Respuesta: 204 No Content o {"ok": true}.

6. Acciones Específicas (PATCH)​

Para acciones que no son CRUD puro, utilizar PATCH con un verbo en la ruta:

PATCH /api/v1/[entidad]/{id}/desactivar
PATCH /api/v1/[entidad]/{id}/reactivar
PATCH /api/v1/[entidad]/{id}/aprobar

Códigos de Estado HTTP​

Éxito (2xx)​

CódigoNombreCuándo Usarlo
200OKOperación exitosa (GET, PUT, PATCH).
201CreatedRecurso creado exitosamente (POST).
204No ContentOperación exitosa sin contenido (DELETE).

Error del Cliente (4xx)​

CódigoNombreCuándo Usarlo
400Bad RequestDatos inválidos o formato incorrecto.
401UnauthorizedAutenticación requerida o token inválido.
403ForbiddenUsuario autenticado pero sin permisos.
404Not FoundRecurso no encontrado.
409ConflictConflicto de estado (ej: duplicado).
422Unprocessable EntityError de validación de Pydantic.

Error del Servidor (5xx)​

CódigoNombreCuándo Usarlo
500Internal Server ErrorError inesperado en el servidor.
503Service UnavailableServicio temporalmente no disponible.

Estructura de Respuestas de Error​

Todas las respuestas de error deben seguir una estructura consistente:

{
"error": "ValidationError",
"message": "Error de validación en los datos enviados",
"details": [{ "field": "Email", "message": "El email es requerido", "value": null }],
"status_code": 400
}

DTO de Error (Python)​

from pydantic import BaseModel
from typing import List, Optional

class ErrorDetailDTO(BaseModel):
field: str
message: str
value: Optional[str] = None

class ErrorResponseDTO(BaseModel):
error: str
message: str
details: Optional[List[ErrorDetailDTO]] = None
status_code: int

Buenas Prácticas​

✅ Hacer​

  • Usar verbos HTTP correctos para cada operación.
  • Incluir siempre limit máximo para evitar consultas masivas.
  • Retornar el código de estado HTTP apropiado.
  • Documentar cada endpoint con OpenAPI (FastAPI lo hace automáticamente).

❌ Evitar​

  • URLs con verbos: /api/v1/getUsuarios → usar GET /api/v1/usuarios.
  • Mezclar convenciones de nomenclatura en una misma API.
  • Retornar 200 OK con un cuerpo de error en JSON.
  • Exponer IDs internos de la base de datos sin validación.

Temas Relacionados​