Módulo 08: Servicios Web y APIs REST
Objetivos del módulo
- Comprender qué es una API y cómo funciona REST
- Conocer los métodos HTTP y códigos de estado
- Entender JSON como formato de intercambio
- Saber leer documentación de APIs (Swagger/OpenAPI)
- Hacer peticiones manuales para entender el flujo
1. ¿Qué es una API?
Una API (Application Programming Interface) es un contrato que define cómo dos sistemas se comunican entre sí.
graph LR
A[Cliente<br/>App/Navegador] -->|Petición HTTP| B[API<br/>Servidor]
B -->|Respuesta JSON| A
B --> C[(Base de datos)]
style A fill:#2196F3,color:white
style B fill:#4CAF50,color:white
Analogía
La API es como un camarero en un restaurante:
- Tú (cliente) haces un pedido (request)
- El camarero (API) lo lleva a la cocina (servidor/BD)
- La cocina prepara la comida y el camarero te la trae (response)
2. REST (Representational State Transfer)
REST es un estilo de arquitectura para APIs web. No es un protocolo, es un conjunto de principios.
Principios REST
| Principio | Descripción |
|---|---|
| Stateless | Cada petición contiene toda la información necesaria |
| Client-Server | Cliente y servidor son independientes |
| Uniform Interface | URLs predecibles y consistentes |
| Cacheable | Las respuestas pueden cachearse |
| Layered | Puede haber capas intermedias (proxy, load balancer) |
Recursos y URLs
Cada recurso tiene una URL única:
| Recurso | URL |
|---|---|
| Lista de usuarios | GET /api/usuarios |
| Usuario específico | GET /api/usuarios/42 |
| Pedidos de un usuario | GET /api/usuarios/42/pedidos |
| Producto concreto | GET /api/productos/15 |
📘 Concepto: Las URLs usan sustantivos (no verbos). El verbo HTTP indica la acción.
3. Métodos HTTP (verbos)
| Método | Acción | Ejemplo | Body |
|---|---|---|---|
| GET | Leer/obtener | GET /api/usuarios | No |
| POST | Crear | POST /api/usuarios | Sí (datos del nuevo usuario) |
| PUT | Actualizar (completo) | PUT /api/usuarios/42 | Sí (todos los campos) |
| PATCH | Actualizar (parcial) | PATCH /api/usuarios/42 | Sí (solo los campos a cambiar) |
| DELETE | Eliminar | DELETE /api/usuarios/42 | No |
CRUD ↔ HTTP
| Operación | HTTP | URL | Body |
|---|---|---|---|
| Create | POST | /api/productos | { "nombre": "Camiseta", "precio": 19.99 } |
| Read (todos) | GET | /api/productos | — |
| Read (uno) | GET | /api/productos/5 | — |
| Update | PUT | /api/productos/5 | { "nombre": "Camiseta XL", "precio": 24.99 } |
| Delete | DELETE | /api/productos/5 | — |
4. Códigos de estado HTTP
Categorías
| Rango | Categoría | Significado |
|---|---|---|
| 1xx | Informacional | Procesando |
| 2xx | Éxito | Todo correcto |
| 3xx | Redirección | El recurso se movió |
| 4xx | Error del cliente | La petición es incorrecta |
| 5xx | Error del servidor | El servidor falló |
Códigos más comunes
| Código | Nombre | Significado | Cuándo aparece |
|---|---|---|---|
| 200 | OK | Petición exitosa | GET exitoso |
| 201 | Created | Recurso creado | POST exitoso |
| 204 | No Content | Éxito sin contenido | DELETE exitoso |
| 400 | Bad Request | Datos incorrectos | JSON mal formado, campo faltante |
| 401 | Unauthorized | No autenticado | Sin token o token inválido |
| 403 | Forbidden | Sin permisos | Token válido pero sin autorización |
| 404 | Not Found | No encontrado | URL o recurso inexistente |
| 405 | Method Not Allowed | Método no permitido | POST donde solo acepta GET |
| 409 | Conflict | Conflicto | Email ya registrado |
| 422 | Unprocessable Entity | Validación fallida | Datos del formato correcto pero inválidos |
| 429 | Too Many Requests | Rate limit | Demasiadas peticiones |
| 500 | Internal Server Error | Error del servidor | Bug en el código del servidor |
| 502 | Bad Gateway | Proxy error | El servidor upstream falló |
| 503 | Service Unavailable | Servicio no disponible | Mantenimiento |
5. JSON (JavaScript Object Notation)
JSON es el formato estándar para intercambiar datos en APIs REST.
Sintaxis
{
"id": 42,
"nombre": "Ana García",
"email": "ana@mail.com",
"edad": 28,
"activo": true,
"direccion": {
"calle": "Calle Mayor 10",
"ciudad": "Madrid",
"codigoPostal": "28001"
},
"telefonos": ["+34 612345678", "+34 698765432"],
"roles": ["usuario", "admin"]
}
Tipos de datos en JSON
| Tipo | Ejemplo |
|---|---|
| String | "texto" |
| Number | 42, 3.14 |
| Boolean | true, false |
| Null | null |
| Object | { "clave": "valor" } |
| Array | [1, 2, 3] |
JSON en peticiones y respuestas
Request (POST /api/usuarios):
{
"nombre": "Carlos López",
"email": "carlos@mail.com",
"password": "MiClave123!"
}
Response (201 Created):
{
"id": 43,
"nombre": "Carlos López",
"email": "carlos@mail.com",
"creadoEn": "2024-12-01T10:30:00Z"
}
6. Headers HTTP
Headers de petición comunes
| Header | Uso | Ejemplo |
|---|---|---|
Content-Type | Formato del body | application/json |
Accept | Formato deseado de respuesta | application/json |
Authorization | Token de autenticación | Bearer eyJhbGciOi... |
User-Agent | Identifica al cliente | PostmanRuntime/7.36.1 |
Headers de respuesta comunes
| Header | Uso | Ejemplo |
|---|---|---|
Content-Type | Formato de la respuesta | application/json; charset=utf-8 |
Content-Length | Tamaño en bytes | 156 |
Cache-Control | Directivas de caché | no-cache |
X-RateLimit-Remaining | Peticiones restantes | 98 |
7. Autenticación
Tipos comunes
| Tipo | Cómo funciona |
|---|---|
| API Key | Clave en header o query param: ?api_key=abc123 |
| Basic Auth | Authorization: Basic base64(user:password) |
| Bearer Token | Authorization: Bearer <token_jwt> |
| OAuth 2.0 | Flujo de autorización con tokens de acceso/refresh |
JWT (JSON Web Token)
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9. ← Header (algoritmo)
eyJzdWIiOiI0MiIsIm5hbWUiOiJBbmEiLCJyb2xlIjoiYWRtaW4ifQ. ← Payload (datos)
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c ← Firma
8. Swagger / OpenAPI
Swagger es una herramienta que genera documentación interactiva de APIs.
Ejemplo de documentación
openapi: 3.0.0
info:
title: API de Tienda
version: 1.0.0
paths:
/api/productos:
get:
summary: Listar todos los productos
responses:
'200':
description: Lista de productos
post:
summary: Crear un producto
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
nombre:
type: string
precio:
type: number
responses:
'201':
description: Producto creado
'400':
description: Datos inválidos
💡 Consejo: Las APIs con ASP.NET Core generan Swagger automáticamente en
/swagger. Úsalo para explorar endpoints antes de escribir tests.
9. Qué probar en una API
| Qué probar | Ejemplo |
|---|---|
| Códigos de estado | GET retorna 200, POST retorna 201 |
| Estructura de respuesta | Tiene campos id, nombre, email |
| Tipos de datos | id es número, email es string |
| Validaciones | POST sin email retorna 400 |
| Autenticación | Sin token retorna 401, token expirado retorna 401 |
| Autorización | Usuario normal no puede DELETE admin |
| Límites | Paginación funciona, rate limiting activo |
| Errores | JSON inválido retorna 400 con mensaje claro |
| Concurrencia | Dos PUT simultáneos no corrompen datos |
| Performance | Respuesta en < 200ms |
10. Ejercicios
Ejercicio 1
Investiga la API pública de https://jsonplaceholder.typicode.com/. Identifica: todos los endpoints, métodos soportados y estructura de las respuestas.
Ejercicio 2
Para una API de biblioteca, escribe el contrato completo (URLs + métodos + request/response) para los recursos: libros, autores, préstamos.
Ejercicio 3
Lista 10 casos de prueba para el endpoint POST /api/usuarios que recibe nombre, email y password.
Resumen
| Concepto | Descripción |
|---|---|
| API REST | Interfaz basada en recursos + verbos HTTP |
| GET/POST/PUT/DELETE | Leer/Crear/Actualizar/Eliminar |
| Códigos 2xx/4xx/5xx | Éxito / Error cliente / Error servidor |
| JSON | Formato de datos: { "clave": "valor" } |
| Headers | Metadatos de la petición/respuesta |
| JWT | Token de autenticación codificado |
| Swagger | Documentación interactiva de la API |