Saltar a contenido

ADR-002: Estilo de API - REST vs GraphQL


Proposito

ADR para la decision del estilo de API del Sistema de Reservas de Turnos Medicos.


Metadata

Campo Valor
ID ADR-002
Fecha 2025-02-15
Estado Accepted
Decisores Carlos Ramirez, Ana Torres (frontend lead), Maria Lopez

Contexto

Necesitamos definir como el frontend web (y futura app mobile) se comunicara con el backend. El sistema tiene:

  • CRUD basico: Usuarios, clinicas, especialidades.
  • Queries complejas: Buscar disponibilidad con filtros (especialidad, clinica, fecha, medico).
  • Operaciones transaccionales: Reservar turno (crear booking + validar disponibilidad + notificar).
  • Multiples consumidores: Web app (React), futura app mobile, posible integracion con terceros.
  • Equipo: 2 frontend devs con experiencia en REST. Sin experiencia con GraphQL.
  • Timeline: MVP en 3 meses.

Opciones Consideradas

Opcion 1: REST (JSON over HTTP)

Pros: - El equipo completo tiene experiencia. - Estandar de la industria, abundante tooling (Swagger/OpenAPI, Postman). - Caching HTTP nativo (ETags, Cache-Control). - Facil de testear y debuggear (curl, browser). - Compatible con cualquier integracion de terceros.

Contras: - Over-fetching: el endpoint de medicos retorna datos que el frontend no siempre necesita. - Under-fetching: para la pantalla de reserva necesitas llamar a 3 endpoints (medico + disponibilidad + clinica). - Versionado de API requiere disciplina (v1, v2).

Costo estimado: Bajo

Opcion 2: GraphQL

Pros: - El frontend pide exactamente lo que necesita (no over-fetching). - Un solo endpoint para todo. - Schema tipado autodocumentado. - Ideal para pantallas complejas con datos de multiples fuentes.

Contras: - Nadie en el equipo tiene experiencia (curva de aprendizaje). - Caching mas complejo (no caching HTTP nativo). - N+1 queries si no se implementa bien (DataLoader). - Overhead de setup: schema, resolvers, code generation. - Mas dificil de debuggear para juniors.

Costo estimado: Alto (por curva de aprendizaje en timeline apretado)

Opcion 3: REST + BFF (Backend for Frontend)

Pros: - REST estandar con una capa de agregacion para el frontend. - Resuelve under-fetching con endpoints compuestos (ej: /booking-flow retorna medico + disponibilidad + clinica). - Permite evolucionar a GraphQL despues sin reescribir el core.

Contras: - Capa adicional que mantener. - Puede volverse un "god endpoint" si no se disciplina. - Over-engineering para un MVP.

Costo estimado: Medio


Decision

Opcion elegida: REST (JSON over HTTP) con endpoints bien disenados

Razon principal: El equipo tiene experiencia, el timeline es apretado, y el dominio no tiene la complejidad de queries que justifique GraphQL en esta etapa.

Detalles: - Disenaremos endpoints "compuestos" donde tenga sentido (ej: GET /doctors/:id/availability retorna disponibilidad con datos del medico y clinica) para evitar under-fetching en los flujos criticos. - Usaremos OpenAPI 3.0 para documentacion y generacion de tipos. - Seguiremos convenciones REST estandar: verbos HTTP, codigos de status, paginacion con cursor.

Reconsiderariamos si: Agregamos una app mobile con requerimientos de datos muy diferentes al web (justificaria GraphQL o BFF).


Consecuencias

Positivas

  • Velocidad de desarrollo: el equipo arranca sin curva de aprendizaje.
  • Tooling maduro: OpenAPI, Postman, generacion de SDKs.
  • Facil de integrar con terceros (clinicas, obras sociales).
  • HTTP caching nativo para endpoints de lectura.

Negativas

  • Algunos endpoints tendran over-fetching (aceptable para MVP).
  • Si la app mobile tiene necesidades muy distintas, tendremos que crear endpoints adicionales.

Neutras

  • Necesitamos disciplina en el diseno de endpoints para no caer en CRUD puro sin logica de dominio.
  • Documentar la API con OpenAPI es trabajo extra pero paga a largo plazo.

Plan de Implementacion

  1. Definir convenciones REST del proyecto (naming, paginacion, errores).
  2. Disenar los contratos de API en 04-api-contracts/.
  3. Configurar Swagger/OpenAPI con NestJS.
  4. Implementar endpoints core: auth, doctors, bookings.
  5. Generar tipos TypeScript desde OpenAPI para el frontend.

Referencias


Checklist de Completitud

  • Contexto documentado con hechos
  • Al menos 2 opciones evaluadas
  • Decision justificada con razonamiento
  • Consecuencias positivas y negativas listadas
  • Revisada por otro ingeniero
  • Derivados generados (contratos de API en 04-api-contracts)

Archivos relacionados