Actualiza la documentación para reflejar el cambio de Express a Fastify en el backend y ajusta las notas de la PoC en lecciones aprendidas.
This commit is contained in:
148
docs/api-integration.md
Normal file
148
docs/api-integration.md
Normal file
@@ -0,0 +1,148 @@
|
||||
# Integración de APIs externas — Prioridad y guía práctica
|
||||
|
||||
## Objetivo
|
||||
|
||||
Definir APIs prioritarias para el MVP, cómo obtener credenciales, ejemplos de uso y estrategias de robustez (rate limit, retries, fallback y normalización de datos).
|
||||
|
||||
---
|
||||
|
||||
## APIs priorizadas (MVP)
|
||||
|
||||
1. **IGDB (prioridad alta)**
|
||||
2. **RAWG (prioridad alta)**
|
||||
3. **TheGamesDB (prioridad media)**
|
||||
|
||||
---
|
||||
|
||||
## IGDB
|
||||
|
||||
- **Obtener credenciales**: registrar una app en Twitch Developer Console para obtener `CLIENT_ID` y `CLIENT_SECRET`. Obtener token con grant type `client_credentials` (POST a `https://id.twitch.tv/oauth2/token`).
|
||||
|
||||
- **Endpoints principales**: `POST https://api.igdb.com/v4/games` (consulta flexible via body con sintaxis IGDB), `POST https://api.igdb.com/v4/covers`, `POST https://api.igdb.com/v4/platforms`.
|
||||
|
||||
- **Ejemplo (buscar)**:
|
||||
|
||||
```bash
|
||||
# Obtener token
|
||||
curl -X POST 'https://id.twitch.tv/oauth2/token?client_id=$IGDB_CLIENT_ID&client_secret=$IGDB_CLIENT_SECRET&grant_type=client_credentials'
|
||||
|
||||
# Buscar juegos
|
||||
curl -X POST 'https://api.igdb.com/v4/games' \
|
||||
-H "Client-ID: $IGDB_CLIENT_ID" \
|
||||
-H "Authorization: Bearer $IGDB_TOKEN" \
|
||||
-H 'Accept: application/json' \
|
||||
--data 'fields id,name,first_release_date,platforms.name,genres.name,cover.url; search "zelda"; limit 5;'
|
||||
```
|
||||
|
||||
- **Respuesta (esquemática)**:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": 12345,
|
||||
"name": "Ejemplo",
|
||||
"first_release_date": 1459468800,
|
||||
"platforms": [{ "name": "Nintendo Switch" }],
|
||||
"cover": { "url": "//images.igdb.com/...jpg" }
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
- **Límites y manejo**: la API puede devolver `429` o cabeceras de límite; implementar retries exponenciales (ej. 3 intentos) y respetar `Retry-After`. Implementar circuit breaker si la API falla repetidamente.
|
||||
- **Atribución**: mostrar origen de datos (ej. "Datos: IGDB") según términos del servicio.
|
||||
|
||||
---
|
||||
|
||||
## RAWG
|
||||
|
||||
- **Obtener credenciales**: registrarse en RAWG para obtener `RAWG_API_KEY` (https://rawg.io/apidocs).
|
||||
- **Endpoints principales**: `GET https://api.rawg.io/api/games?key=API_KEY&search=...`, `GET https://api.rawg.io/api/games/{id}`.
|
||||
- **Ejemplo**:
|
||||
|
||||
```bash
|
||||
curl 'https://api.rawg.io/api/games?key=$RAWG_API_KEY&search=zelda&page_size=5'
|
||||
```
|
||||
|
||||
- **Respuesta (esquemática)**:
|
||||
|
||||
```json
|
||||
{
|
||||
"count": 100,
|
||||
"results": [
|
||||
{ "id": 3498, "name": "GTA V", "released": "2013-09-17", "background_image": "https://..." }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
- **Límites y manejo**: RAWG suele tener límites por clave/plan; cachear y fallback a otros proveedores si falla.
|
||||
- **Atribución**: revisar condiciones y mostrar HTTP o texto de fuente si es requerido por el proveedor.
|
||||
|
||||
---
|
||||
|
||||
## TheGamesDB
|
||||
|
||||
- **Obtener credenciales**: crear cuenta y generar API Key en https://thegamesdb.net.
|
||||
- **Endpoints**: búsqueda por nombre y detalles (`/v1/Games/ByGameName?name=...`, `/v1/Games/ByGameID?id=...`).
|
||||
- **Ejemplo**:
|
||||
|
||||
```bash
|
||||
curl -H 'Authorization: Bearer $THEGAMESDB_KEY' 'https://api.thegamesdb.net/v1/Games/ByGameName?name=zelda'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Estrategia de fallback y normalización
|
||||
|
||||
- **Orden de prioridad**: IGDB → RAWG → TheGamesDB (configurable).
|
||||
- **Normalización (mapping)**:
|
||||
- `title` ← `name`
|
||||
- `platform` ← `platforms[].name`
|
||||
- `release_date` ← `first_release_date` / `released` → convertir a ISO 8601
|
||||
- `genres` ← `genres[].name`
|
||||
- `cover_url` ← `cover.url` / `background_image`
|
||||
- `external_ids` ← `{ igdb: id, rawg: id, thegamesdb: id }`
|
||||
|
||||
- **Fallback**: si IGDB no tiene portada, intentar RAWG; si falla, usar TheGamesDB. Registrar la fuente usada.
|
||||
|
||||
---
|
||||
|
||||
## Caché y almacenamiento de artwork
|
||||
|
||||
- **Caché metadata**: LRU en memoria o Redis con TTL (por ejemplo 24h) para evitar sobrecargar APIs.
|
||||
- **Almacenamiento de imágenes**: descargar y optimizar con `sharp` (crear versiones: thumb, medium), almacenar en `storage/artwork/{gameId}/cover.jpg` o S3.
|
||||
- **Servicio proxy**: servir imágenes desde backend para no exponer keys ni URLs externas.
|
||||
|
||||
---
|
||||
|
||||
## Manejo de errores y resiliencia
|
||||
|
||||
- Implementar **retries** exponenciales con jitter (3 intentos).
|
||||
- Implementar **circuit breaker** para desconectar llamadas a un proveedor fuera de servicio por N minutos.
|
||||
- Limitar concurrencia por proveedor (p. ej. 5 llamadas simultáneas) y usar colas para trabajos masivos (enriquecimiento masivo).
|
||||
|
||||
---
|
||||
|
||||
## Variables de entorno (ejemplos)
|
||||
|
||||
```
|
||||
IGDB_CLIENT_ID=...
|
||||
IGDB_CLIENT_SECRET=...
|
||||
RAWG_API_KEY=...
|
||||
THEGAMESDB_API_KEY=...
|
||||
EXTERNAL_API_CONCURRENCY=5
|
||||
```
|
||||
|
||||
> Nota: **Nunca** exponer estas claves en el cliente; siempre pasar por el backend.
|
||||
|
||||
---
|
||||
|
||||
## Fuentes
|
||||
|
||||
- IGDB API docs, RAWG API docs, TheGamesDB API docs.
|
||||
- Patrones: retries, circuit breakers (ej. libraries: `p-retry`, `cockatiel`).
|
||||
|
||||
---
|
||||
|
||||
**Metadatos**
|
||||
Autor: Quasar (investigación automatizada)
|
||||
Última actualización: 2026-02-07
|
||||
Reference in New Issue
Block a user