1. APIs y Protocolos
Interfaces para comunicación entre sistemas: REST, GraphQL, gRPC, WebSockets y más.
1.1 🎯 Elegir Protocolo
Qué: Definir cómo sistemas se comunican.
Por qué: Impacta performance, developer experience, escalabilidad.
Quién: Arquitectos, backend developers.
Esfuerzo: Decisión difícil de cambiar una vez adoptada.
1.2 🌐 REST (Representational State Transfer)
Qué: APIs basadas en HTTP con recursos y verbos.
Por qué: Estándar universal, cacheable, stateless.
| Aspecto | Qué | Cómo |
|---|---|---|
| Recursos | Sustantivos (entidades) | /users, /orders, /products |
| Verbos HTTP | Acciones sobre recursos | GET (leer), POST (crear), PUT (actualizar), DELETE (borrar) |
| Códigos Status | Resultado de operación | 200 OK, 201 Created, 400 Bad Request, 404 Not Found, 500 Server Error |
| Idempotencia | Mismo request → mismo resultado | GET, PUT, DELETE idempotentes. POST no |
| HATEOAS | Hypermedia as Engine of State | Responses incluyen links a recursos relacionados |
Ejemplo:
GET /api/v1/users/123
Authorization: Bearer <token>
Response 200:
{
"id": 123,
"name": "Alice",
"email": "alice@example.com",
"_links": {
"self": "/users/123",
"orders": "/users/123/orders"
}
}
Ventajas:
- Simplicidad y curva de aprendizaje baja.
- Amplio soporte en browsers, frameworks y herramientas.
- Caching nativo vía HTTP.
- Idempotencia clara en GET/PUT/DELETE.
- Estándar universal, interoperable.
Desventajas:
- Overfetching/underfetching: el cliente recibe más o menos datos de los necesarios.
- Multiplicidad de endpoints → mantenimiento más complejo.
- Falta de tipado fuerte (JSON libre).
- HATEOAS poco usado en la práctica.
1.3 🔍 GraphQL
Qué: Query language para APIs con schema tipado.
Por qué: Cliente pide exactamente lo que necesita, no más ni menos.
| Concepto | Qué | Ejemplo |
|---|---|---|
| Schema | Tipos y relaciones | type User { id: ID! name: String! posts: [Post] } |
| Query | Leer datos | { user(id: "123") { name email } } |
| Mutation | Modificar datos | mutation { createUser(input: {...}) { id } } |
| Subscription | Real-time updates | subscription { messageAdded { id text } } |
| Resolver | Función que obtiene datos | User.posts: (parent) => fetchPosts(parent.id) |
Ventajas:
- Evita overfetching/underfetching: cliente pide exactamente lo que necesita.
- Un único endpoint centralizado.
- Schema tipado y autodocumentado.
- Soporta queries, mutations y subscriptions (real‑time).
- Ecosistema rico (Apollo, Hasura).
Desventajas:
- Curva de aprendizaje mayor, requiere definir schema y resolvers.
- Caching complejo (usa POST y un solo endpoint).
- Riesgo de queries costosas (N+1).
- Seguridad: requiere control de profundidad y complejidad de queries.
Herramientas: Apollo, Hasura, GraphQL Yoga
1.4 ⚡ gRPC
Qué: RPC framework con Protocol Buffers binario.
Por qué: Performance, tipado fuerte, streaming nativo.
| Aspecto | Qué | Ventaja |
|---|---|---|
| Protocol Buffers | Serialización binaria | Más pequeño y rápido que JSON |
| HTTP/2 | Multiplexing, server push | Menos conexiones |
| Streaming | Bidireccional | Server/Client/Bidirectional streams |
| Code generation | Clientes/servers automáticos | Type-safe |
Ejemplo .proto:
service UserService {
rpc GetUser (GetUserRequest) returns (User);
rpc StreamUsers (StreamUsersRequest) returns (stream User);
}
message User {
int32 id = 1;
string name = 2;
string email = 3;
}
Ventajas:
- Serialización binaria (Protocol Buffers) → payloads pequeños y rápidos.
- HTTP/2: multiplexing, server push, menos conexiones.
- Tipado fuerte y generación automática de clientes/servers.
- Streaming bidireccional nativo.
- Ideal para microservicios internos de alta performance.
Desventajas:
- Soporte limitado en browsers (requiere proxy/gateway).
- Curva de aprendizaje alta (proto files, tooling).
- Debugging más complejo que JSON/REST.
- No aprovecha caching HTTP estándar.
Cuándo usar: Microservicios internos, alta performance, streaming.
Herramientas: gRPC, Buf, grpcurl
1.5 🔌 WebSockets
Qué: Conexión bidireccional persistente sobre TCP.
Por qué: Real-time, baja latencia, push de servidor.
| Aspecto | Qué | Cuándo |
|---|---|---|
| Full-duplex | Cliente y servidor envían simultáneamente | Chat, gaming |
| Persistent | Conexión abierta continuamente | Notificaciones en tiempo real |
| Binary/Text | Soporta ambos formatos | Flexible |
Ejemplo:
const ws = new WebSocket('wss://api.example.com/ws');
ws.onmessage = (event) => {
console.log('Message:', event.data);
};
ws.send(JSON.stringify({ type: 'subscribe', channel: 'updates' }));
Ventajas:
- Comunicación full‑duplex en tiempo real.
- Baja latencia, ideal para chat, gaming, dashboards.
- Soporta texto y binario.
- Amplio soporte en navegadores.
Desventajas:
- No cacheable.
- Escalabilidad más compleja (conexiones persistentes).
- Requiere load balancers y proxies compatibles.
- Difícil de depurar comparado con HTTP.
Cuándo usar: Chat, gaming, dashboards en tiempo real, collaborative editing.
Alternativa: Server-Sent Events (SSE) para one-way server→client.
1.6 📨 Server-Sent Events (SSE)
Qué: Streaming unidireccional server→client sobre HTTP.
Por qué: Más simple que WebSockets para notificaciones.
const eventSource = new EventSource('/api/events');
eventSource.addEventListener('update', (event) => {
console.log('Update:', event.data);
});
Cuándo usar: Notificaciones, cotizaciones, progress updates.
Ventajas:
- Simples: usan HTTP estándar.
- Reconexión automática integrada.
- Event IDs permiten reanudar streams.
- Menor complejidad que WebSockets para notificaciones unidireccionales.
Desventajas:
- Solo unidireccional (server → client).
- Basado en texto (no binario).
- Menor soporte en algunos entornos comparado con WebSockets.
- No apto para escenarios de alta concurrencia bidireccional.
1.7 🎯 Event-Driven / Async
Qué: Comunicación basada en eventos via message brokers.
Por qué: Desacopla productores y consumidores, escalable horizontalmente.
Cuándo usar: Workflows complejos, alto throughput, logs.
| Broker | Qué | Cuándo |
|---|---|---|
| RabbitMQ | Message queue con routing | Workflows complejos |
| Apache Kafka | Event streaming distribuido | Alto throughput, logs |
| AWS SQS | Queue serverless | Desacople simple en AWS |
| Redis Pub/Sub | Publish/Subscribe en memoria | Eventos en tiempo real |
Patrones:
- Pub/Sub: Broadcast a múltiples consumidores
- Queues: Work distribution, un consumidor procesa
- Event Sourcing: Eventos como fuente de verdad
Ventajas:
- Desacopla productores y consumidores.
- Escalable horizontalmente.
- Patrones flexibles: Pub/Sub, colas, event sourcing.
- Alta tolerancia a fallos (Kafka, SQS).
- Ideal para sistemas distribuidos.
Desventajas:
- Complejidad operativa (brokers, clusters).
- Latencia mayor que RPC directo.
- Requiere monitoreo y observabilidad avanzada.
- Curva de aprendizaje de cada broker.
1.8 🔄 Webhooks
Qué: HTTP callbacks cuando ocurre evento.
Por qué: Integración event-driven sin polling.
Ejemplo:
POST https://yourapp.com/webhook
X-Signature: sha256=...
{
"event": "payment.succeeded",
"data": {
"amount": 1000,
"currency": "USD"
}
}
Seguridad:
- Validar firma HMAC
- HTTPS obligatorio
- Retry exponential backoff
- Idempotencia en receptor
Ventajas:
- Simples: callbacks HTTP estándar.
- Integración rápida entre sistemas.
- Evitan polling.
- Amplio soporte en SaaS y APIs públicas.
Desventajas:
- Seguridad: requieren validación de firmas y HTTPS.
- Fiabilidad: necesitan reintentos e idempotencia.
- Escalabilidad limitada (cada evento → request).
- Difícil de depurar si el receptor falla.
1.9 📄 Documentación
| Protocolo | Herramienta | Ejemplo |
|---|---|---|
| REST | OpenAPI / Swagger | Spec YAML → Swagger UI |
| GraphQL | Schema introspection | GraphQL Playground |
| gRPC | Protocol Buffers | .proto files → docs |
| WebSockets | AsyncAPI | Spec para async APIs |
| Webhooks | AsyncAPI / OpenAPI | Spec para webhooks |
Ejemplo OpenAPI:
openapi: 3.0.0
paths:
/users/{id}:
get:
summary: Get user by ID
parameters:
- name: id
in: path
required: true
schema:
type: integer
responses:
'200':
description: User found
content:
application/json:
schema:
$ref: '#/components/schemas/User'
1.10 🔐 Autenticación
| Método | Qué | Cuándo | Header |
|---|---|---|---|
| API Key | String estático | Integraciones internas | X-API-Key: abc123 |
| Bearer Token | JWT en header | SPAs, mobile apps | Authorization: Bearer <jwt> |
| OAuth 2.0 | Delegación con tokens | Third-party integrations | Authorization: Bearer <access_token> |
| Basic Auth | Usuario:contraseña en base64 | Desarrollo, admin tools | Authorization: Basic <base64> |
| mTLS | Certificados cliente/servidor | Service-to-service | TLS handshake |
1.11 🎨 Diseño de APIs
| Principio | Qué | Ejemplo |
|---|---|---|
| Versionado | Mantener compatibilidad | /api/v1/, /api/v2/ o header |
| Paginación | Evitar payloads gigantes | ?limit=20&offset=40 o cursor |
| Filtrado | Permitir búsquedas | ?status=active&role=admin |
| Ordenamiento | Control de orden | ?sort=created_at:desc |
| Rate Limiting | Prevenir abuse | X-RateLimit-Remaining: 45 |
| CORS | Controlar origins | Access-Control-Allow-Origin: * |
| Idempotency Keys | Evitar duplicados | Idempotency-Key: uuid header |
1.12 📊 Comparación
| Característica | REST | GraphQL | gRPC | WebSocket | Webhook |
|---|---|---|---|---|---|
| Protocol | HTTP | HTTP | HTTP/2 | TCP | HTTP |
| Payload | JSON | JSON | Protobuf | Binary/Text | JSON |
| Typing | No | Sí (schema) | Sí (protobuf) | No | No |
| Streaming | No | Sí (subscriptions) | Sí | Sí | No |
| Caching | Fácil (HTTP) | Difícil | No | No | No |
| Browser Support | ✅ | ✅ | Limitado | ✅ | ✅ |
| Curva de Aprendizaje | Bajo | Medio | Alto | Medio | Medio |
1.13 🚫 Anti-patrones
| Anti-patrón | Problema | Solución |
|---|---|---|
| Verbos en URLs | /getUser, /createOrder |
Usar HTTP verbs: GET, POST |
| Sin versionado | Breaking changes rompen clientes | /v1/, deprecation notices |
| Respuestas inconsistentes | Diferentes estructuras por endpoint | Estandarizar formato |
| Sin rate limiting | Abuse, DDoS | Implementar límites |
| Exponer IDs internos | Security risk (Enumeration attacks) | Usar UUIDs públicos |