# Documentación de la API

Esta página cubre los estándares para documentar APIs usando especificaciones OpenAPI en todos los servicios de Decentraland.

## Objetivos

Nuestro enfoque de documentación de API garantiza:

* **Estandarización** - Especificaciones OpenAPI consistentes en todos los servicios
* **Automatización** - Validación, empaquetado y despliegue mediante GitHub Actions
* **Centralización** - Toda la documentación de servicios publicada a través de GitBook
* **Propiedad** - La documentación vive en el repositorio de cada servicio
* **Accesibilidad** - Referencias de API amigables para contribuidores y actualizadas

***

## Estructura del repositorio

Cada repositorio de servicio DEBE incluir un `/docs` directorio con la siguiente estructura:

```bash
/docs
  openapi.yaml        # Fuente de verdad (OpenAPI 3.1)
  openapi.json        # Generado automáticamente en CI para Hugo/renderers
  index.html          # Documentación independiente generada automáticamente (opcional)
```

### Requisitos de archivos

#### `openapi.yaml`

* **DEBE** ser el archivo fuente canónico
* **DEBE** usar la especificación OpenAPI 3.1
* **PUEDE** tener un prefijo que identifique el servicio (p. ej., `worlds-openapi.yaml`)
* **PUEDE** dividirse en `components/` o `examples/` directorios si es necesario

#### `openapi.json`

* Generado automáticamente durante CI/CD
* Usado por Hugo y otros renderers
* No editar manualmente

#### `index.html`

* Documentación independiente generada automáticamente
* Construido usando Redocly
* Desplegado en GitHub Pages

***

## Estándares OpenAPI

Al escribir `openapi.yaml`, sigue estas convenciones para asegurar consistencia y claridad.

### Resumen del endpoint

**DEBE** refleja la ruta real del endpoint:

```yaml
# ✅ Bueno: Ruta de endpoint clara
paths:
  /world/{world_name}/about:
    get:
      summary: /world/{world_name}/about
      description: Recupera información sobre un world específico
      
# ❌ Malo: Resumen genérico
paths:
  /world/{world_name}/about:
    get:
      summary: Obtener info del world
```

### Operation ID

**DEBE** incluye el nombre del servicio para unicidad global:

```yaml
# ✅ Bueno: Operation ID con prefijo de servicio
operationId: worldsContentServer_getWorldAbout

# ✅ Bueno: Otro ejemplo
operationId: socialService_getFriends

# ❌ Malo: Genérico, podría entrar en conflicto
operationId: getAbout
```

**Convención de nombres**: `{serviceName}_{operationDescription}`

* Usa camelCase
* Sé descriptivo pero conciso
* Incluye el contexto del método HTTP cuando sea útil (p. ej., `createUser`, `deleteParcel`)

### Versionado

**DEBE** usa versionado semántico (`MAJOR.MINOR.PATCH`) en `info.version`:

```yaml
openapi: 3.1.0
info:
  title: Worlds Content Server API
  version: 1.2.0  # Versionado semántico
  description: API para gestionar Decentraland worlds
```

**Reglas para incrementar la versión**:

* **MAJOR**: Cambios incompatibles (cambios rompientes en la API)
* **MINOR**: Nueva funcionalidad (compatible hacia atrás)
* **PATCH**: Correcciones de bugs (compatible hacia atrás)

### Etiquetas y agrupación

**DEBE** usa tags para agrupar endpoints relacionados:

```yaml
tags:
  - name: Worlds
    description: Operaciones de gestión de worlds
  - name: Deployments
    description: Operaciones de despliegue de worlds
  - name: Health
    description: Endpoints de chequeo de salud

paths:
  /worlds:
    get:
      tags:
        - Worlds
      summary: /worlds
      operationId: worldsContentServer_listWorlds
      
  /worlds/{world_name}/about:
    get:
      tags:
        - Worlds
      summary: /worlds/{world_name}/about
      operationId: worldsContentServer_getWorldAbout
```

{% hint style="info" %}
Las operaciones se agrupan por tag en la navegación de GitBook. Agrupa endpoints relacionados bajo el mismo tag para una mejor organización.
{% endhint %}

### Ejemplo completo

```yaml
openapi: 3.1.0
info:
  title: Social Service API
  version: 2.1.0
  description: API para gestionar interacciones sociales en Decentraland
  contact:
    name: Decentraland Contributors
    url: https://decentraland.org

servers:
  - url: https://social.decentraland.org
    description: Servidor de producción
  - url: https://social.decentraland.zone
    description: Servidor de staging

tags:
  - name: Friends
    description: Gestión de amigos
  - name: Blocked Users
    description: Operaciones de bloqueo de usuarios

paths:
  /friends:
    get:
      tags:
        - Friends
      summary: /friends
      operationId: socialService_getFriends
      description: Devuelve la lista de amigos del usuario autenticado
      parameters:
        - name: limit
          in: query
          schema:
            type: integer
            default: 50
            maximum: 100
        - name: offset
          in: query
          schema:
            type: integer
            default: 0
      responses:
        '200':
          description: Respuesta exitosa
          content:
            application/json:
              schema:
                type: object
                properties:
                  friends:
                    type: array
                    items:
                      $ref: '#/components/schemas/Friend'
        '401':
          description: No autorizado

components:
  schemas:
    Friend:
      type: object
      required:
        - address
        - createdAt
      properties:
        address:
          type: string
          description: Dirección de Ethereum del amigo
        createdAt:
          type: string
          format: date-time
          description: Cuando se estableció la amistad
```

***

## Desarrollo local

### Previsualizar documentación localmente

Usa Redocly CLI para previsualizar tu documentación OpenAPI:

```bash
# Construir documentación HTML
yarn redocly build-docs docs/openapi.yaml -o docs/index.html

# Luego abre docs/index.html en tu navegador
```

### Agregar a package.json

Agrega un script de build por conveniencia:

```json
{
  "scripts": {
    "build:api": "redocly bundle docs/openapi.yaml -o docs/openapi.json --ext json && redocly build-docs docs/openapi.yaml -o docs/index.html",
    "preview:api": "redocly preview-docs docs/openapi.yaml"
  }
}
```

### Instalar Redocly CLI

```bash
# Usando npm
npm install -g @redocly/cli

# Usando yarn
yarn global add @redocly/cli
```

### Validar especificación OpenAPI

```bash
# Valida tu especificación
redocly lint docs/openapi.yaml

# Empaquetar y validar
redocly bundle docs/openapi.yaml
```

***

## Configuración de automatización

### Paso 1: Configurar secretos de GitBook

Para publicar especificaciones de API en GitBook, agrega estos secretos a tu repositorio:

**Settings → Secrets and variables → Actions → New repository secret**

| Nombre del secreto        | Descripción                         | Dónde encontrar                 |
| ------------------------- | ----------------------------------- | ------------------------------- |
| `GITBOOK_ORGANIZATION_ID` | El ID de tu organización en GitBook | GitBook Settings → Organization |
| `GITBOOK_TOKEN`           | Token de la API de GitBook          | GitBook Settings → API Tokens   |

{% hint style="warning" %}
Estos secretos DEBEN estar configurados para que el flujo de trabajo automatizado publique en GitBook.
{% endhint %}

### Paso 2: Agregar workflow de GitHub Actions

Crear `.github/workflows/build-api-docs.yml` en tu repositorio:

```yaml
name: build-app-docs

on:
  push:
    branches: [main]
    paths:
      - 'docs/**'
  pull_request:
    paths:
      - 'docs/**'

jobs:
  build:
    uses: decentraland/platform-actions/.github/workflows/apps-docs.yml@main
    with:
      api-spec-file: 'docs/openapi.yaml'
      output-file: 'docs/index.html'
      output-directory: './docs'
      api-spec-name: '{service-name}-api'  # p. ej., 'social-service-api'
      node-version: '20'
    secrets: inherit
```

**Parámetros**:

* `api-spec-file`: Ruta a tu especificación OpenAPI (usualmente `docs/openapi.yaml`)
* `output-file`: Dónde generar la documentación HTML
* `output-directory`: Directorio para los archivos de salida
* `api-spec-name`: Nombre único para tu especificación de API (usado en GitBook)
* `node-version`: Versión de Node.js a usar

**Este workflow hará**:

1. ✅ Validar la especificación OpenAPI
2. ✅ Empaquetar la especificación en un único archivo
3. ✅ Construir documentación HTML estática usando Redocly
4. ✅ Desplegar automáticamente en GitHub Pages
5. ✅ Publicar la especificación en GitBook (si los secretos están configurados)

### Paso 3: Habilitar GitHub Pages

Configura GitHub Pages en tu repositorio:

1. Ve a **Settings → Pages**
2. Bajo **Build and deployment**:
   * Establece **Source** a **GitHub Actions**
3. Asegúrate de que exista un environment llamado **github-pages**
4. Guardar configuraciones

Después de la primera ejecución exitosa del workflow, tu documentación estará disponible en:

* **Docs HTML**: `https://decentraland.github.io/<repo>/index.html`
* **Especificación OpenAPI**: `https://decentraland.github.io/<repo>/openapi.yaml`
* **JSON empaquetado**: `https://decentraland.github.io/<repo>/openapi.json`

{% hint style="success" %}
Estas URLs permanecen válidas mientras el repositorio exista y GitHub Pages esté habilitado.
{% endhint %}

***

## Agregar a GitBook

Una vez que tu documentación de API esté desplegada, agrégala a la documentación centralizada en GitBook.

### Adición manual (proceso actual)

1. Navega al espacio de GitBook
2. Ve a la **API Reference** sección
3. Haz clic en **Add API Reference**
4. Introduce los detalles de tu servicio:
   * **Name**: El nombre de tu servicio (p. ej., "Social Service")
   * **OpenAPI URL**: `https://decentraland.github.io/{repo-name}/openapi.yaml`
5. Guardar

### Funciones de integración de GitBook

GitBook hará automáticamente:

* Parsear tu especificación OpenAPI
* Generar documentación interactiva de la API
* Crear navegación de endpoints basada en tags
* Proveer funcionalidad de "Try it"
* Mantener la documentación sincronizada cuando actualices la especificación

***

## Flujo de configuración completo

### Configuración inicial

{% @mermaid/diagram content="graph TD
A\[Create /docs/openapi.yaml] --> B\[Add GitHub Actions workflow]
B --> C\[Configure GitBook secrets]
C --> D\[Enable GitHub Pages]
D --> E\[Push to main branch]
E --> F\[Workflow runs automatically]
F --> G\[Docs deployed to GitHub Pages]
G --> H\[Add to GitBook manually]" %}

### Actualizaciones continuas

{% @mermaid/diagram content="graph LR
A\[Update openapi.yaml] --> B\[Create PR]
B --> C\[Workflow validates]
C --> D\[Merge to main]
D --> E\[Auto-deploy to GitHub Pages]
E --> F\[GitBook syncs automatically]" %}

***

## Buenas prácticas

### Calidad de la documentación

* **Sé descriptivo**: Escribe resúmenes y descripciones claras
* **Proporciona ejemplos**: Incluye ejemplos de request/response
* **Documenta errores**: Describe todas las posibles respuestas de error
* **Usa components**: Reutiliza esquemas vía `$ref` para evitar duplicación
* **Agrega descripciones**: Cada parámetro, propiedad y respuesta debe tener una descripción

### Ejemplo con buenas prácticas

```yaml
paths:
  /users/{address}/friends:
    get:
      tags:
        - Friends
      summary: /users/{address}/friends
      operationId: socialService_getUserFriends
      description: |
        Recupera una lista paginada de amigos para el usuario especificado.
        Devuelve direcciones de amigos y metadatos incluyendo cuándo se estableció la amistad.
      parameters:
        - name: address
          in: path
          required: true
          description: Dirección de Ethereum del usuario (con prefijo 0x)
          schema:
            type: string
            pattern: '^0x[a-fA-F0-9]{40}$'
          example: '0x1234567890abcdef1234567890abcdef12345678'
        - name: limit
          in: query
          description: Número máximo de amigos a devolver (1-100)
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 50
        - name: offset
          in: query
          description: Número de amigos a omitir para paginación
          schema:
            type: integer
            minimum: 0
            default: 0
      responses:
        '200':
          description: Lista de amigos recuperada con éxito
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FriendsResponse'
              example:
                friends:
                  - address: '0xabcdef...'
                    createdAt: '2024-01-15T10:30:00Z'
                total: 42
                offset: 0
                limit: 50
        '400':
          description: Formato de dirección inválido
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: 'Formato de dirección inválido'
                code: 'INVALID_ADDRESS'
        '404':
          description: Usuario no encontrado
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
```

### Reutilización de esquemas

```yaml
components:
  schemas:
    Error:
      type: object
      required:
        - error
        - code
      properties:
        error:
          type: string
          description: Mensaje de error legible por humanos
        code:
          type: string
          description: Código de error legible por máquina
        details:
          type: object
          description: Contexto adicional del error
          
    PaginatedResponse:
      type: object
      required:
        - offset
        - limit
        - total
      properties:
        offset:
          type: integer
          description: Número de elementos omitidos
        limit:
          type: integer
          description: Máximo de elementos por página
        total:
          type: integer
          description: Número total de elementos disponibles
```

### Esquemas de seguridad

```yaml
components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: Token JWT obtenido desde el endpoint de autenticación

security:
  - BearerAuth: []
```

***

## Validaciones y controles de calidad

### Validación pre-commit

Agrega un hook pre-commit o una comprobación en CI:

```yaml
# .github/workflows/validate-api-spec.yml
name: Validate API Spec

on: [pull_request]

jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: '20'
      - run: npm install -g @redocly/cli
      - run: redocly lint docs/openapi.yaml
```

### Reglas comunes de validación

* Todas las paths tienen operation IDs
* Todas las operaciones tienen tags
* Todos los parámetros tienen descripciones
* Todas las respuestas están documentadas
* Se proporcionan ejemplos
* Los esquemas están referenciados correctamente

***

## Solución de problemas

### El workflow falla

**Problema**: El workflow de GitHub Actions falla

**Soluciones**:

* Revisa los logs del workflow por errores de validación
* Ejecuta `redocly lint docs/openapi.yaml` localmente
* Verifica las rutas de archivos en la configuración del workflow
* Asegúrate de que los secretos estén configurados correctamente

### GitHub Pages no funciona

**Problema**: Los docs no aparecen en la URL de GitHub Pages

**Soluciones**:

* Verifica que GitHub Pages esté habilitado en la configuración del repositorio
* Comprueba que el workflow se haya completado exitosamente
* Espera unos minutos para que GitHub Pages se actualice
* Verifica que el `github-pages` environment exista

### GitBook no se sincroniza

**Problema**: GitBook no muestra la documentación de API actualizada

**Soluciones**:

* Verifica que los secretos de GitBook sean correctos
* Comprueba que la URL OpenAPI sea accesible
* Forzar una actualización manual en GitBook
* Verifica que la especificación OpenAPI sea válida

***

## Migración desde documentación existente

Si tienes documentación de API existente:

1. **Exportar a OpenAPI**: Convertir la documentación existente al formato OpenAPI 3.1
2. **Validar**: Usar `redocly lint` para asegurar el cumplimiento
3. **Agregar workflow**: Configurar la automatización con GitHub Actions
4. **Probar**: Verificar que la documentación se compile y despliegue correctamente
5. **Actualizar enlaces**: Apuntar los enlaces de la documentación antigua a la nueva URL de GitHub Pages
6. **Archivar la documentación antigua**: Mantener la documentación antigua como referencia durante la transición

***

## Próximos pasos

* Revisar el [Well-Known Components](https://github.com/decentraland/docs/blob/main/contributor/contributor-guides/well-known-components/README.md) estándares para la implementación de la API
* Ver [Testing Standards](/contributor/contributor-es/guias-para-colaboradores/testing-standards.md) para las pautas de pruebas de la API
* Consulta ejemplos de API existentes en el [API Reference](https://docs.decentraland.org) sección

## Related Standards

* [Gestión de dependencias](/contributor/contributor-es/guias-para-colaboradores/dependency-management.md) - Gestión de dependencias npm y peerDependencies
* [Well-Known Components](https://github.com/decentraland/docs/blob/main/contributor/contributor-guides/well-known-components/README.md) - Arquitectura WKC para servicios
* [Testing Standards](/contributor/contributor-es/guias-para-colaboradores/testing-standards.md) - Patrones de pruebas para servicios

## Recursos

* **OpenAPI Specification**: [spec.openapis.org](https://spec.openapis.org/oas/latest.html)
* **Redocly CLI**: [redocly.com/docs/cli](https://redocly.com/docs/cli/)
* **Integración de API de GitBook**: [docs.gitbook.com](https://docs.gitbook.com)
* **Repositorio de Platform Actions**: [github.com/decentraland/platform-actions](https://github.com/decentraland/platform-actions)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.decentraland.org/contributor/contributor-es/guias-para-colaboradores/api-documentation.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
