loopback-openapi-3
v1.1.0
Published
Parchea Swagger generado por LoopBack 3 y lo sirve con Redoc
Readme
📘 loopback-openapi-3 (LB3 → OpenAPI 3 + Redoc)
Genera y sirve la documentación de una app LoopBack 3 en OpenAPI 3 usando Redoc.
Características principales:
- Genera
swagger.jsondesde la instancia LB3 (o lo descarga conswaggerUrl) - Aplica un “patch” a los métodos para exponer parámetros de entrada a nivel campo
- Convierte a OpenAPI 3 (
swagger2openapi) - Sirve Redoc en
GET {mountPath}(por defecto/api-docs) - Filtra endpoints automáticamente según
server/model-config.*del entorno - Ignora por defecto el tag/paths de RabbitMQ (opcional)
- Soporta “retagging” de endpoints por modelo (
x-doc), resúmenes (summary) y overview por tag - Permite contenidos de secciones en Markdown externo y grupos de tags
- Auto‑genera secciones desde una estructura de carpetas (no hace falta listar manualmente)
- Salida cacheable en
TMPDIR(evita reinicios de nodemon)
🚀 Instalación
npm install loopback-openapi-3⚙️ Uso básico (boot script)
server/boot/openapi-docs.js
'use strict';
const path = require('path');
const serveDocs = require('loopback-openapi-3').serveDocs;
module.exports = async function(app) {
app.use(serveDocs({
app,
modelsDir: path.join(__dirname, '../../common/models'),
mountPath: '/api-docs',
// modelConfigDir: path.join(__dirname, '..'), // opcional (se infiere)
}));
};Abrí: http://localhost:3000/api-docs
🧩 Opciones de serveDocs
| Opción | Tipo | Default | Descripción |
|--------------------|-----------|-----------------------------------------------------|-------------|
| app | Object | — | Instancia LB3 (requerido si no usás swaggerUrl). |
| swaggerUrl | String | — | Cargar swagger externo en lugar de generarlo. |
| modelsDir | String | ./common/models | Directorio de modelos .json (para el patch). |
| mountPath | String | /api-docs | Ruta donde se sirve Redoc. |
| outputDir | String | os.tmpdir()/openapi-docs-${NODE_ENV} | Carpeta de artefactos (swagger.json, openapi3.json, redoc.html). |
| modelConfigDir | String | inferido desde modelsDir | Directorio server/ que contiene model-config.*. |
| useCache | Boolean | process.env.OPENAPI_DOCS_CACHE === '1' | Si true, reutiliza artefactos en disco. |
| ignoreTags | String[] | env OPENAPI_IGNORE_TAGS ó ['RabbitMQ'] | Tags a ocultar. |
| ignorePaths | String[] | — | Expresiones regulares (string) de paths a ocultar. |
Variables de entorno:
OPENAPI_DOCS_CACHE=1activa cache.OPENAPI_IGNORE_TAGS="RabbitMQ,OtroTag"para ocultar tags.OPENAPI_INCLUDE_RABBITMQ=1para no ocultar RabbitMQ.
📦 server/api-docs-config.json (opcional)
Permite agregar contenido no atado a modelos y organizar el menú.
Campos soportados:
{
"infoDescription": "Markdown…", // overview global (opcional)
"infoDescriptionFile": "docs/intro.md", // o desde archivo MD
"tags": [ // tags adicionales (ej. secciones de contenido)
{ "name": "Overview", "descriptionFile": "docs/overview.md" },
{ "name": "How to authenticate", "descriptionFile": "docs/auth.md" }
],
"keepUnusedTags": false, // si true: conserva todos los tags sin endpoints
"keepTags": ["Overview"], // whitelist de tags a conservar sin endpoints
"autoDocsDir": "../docs/public", // autogenera grupos/tags desde carpetas y .md
// public/
// ├─ Introducción/
// │ ├─ Overview.md
// │ ├─ How to authenticate.md
// │ └─ Endpoints.md
// └─ Concepts/
// ├─ About Deposits.md
// └─ ...
"tagGroups": [ // grupos manuales (opcional)
{ "name": "Introducción", "tags": ["Overview", "How to authenticate"] }
],
"autoGroupRemainingAs": "API" // crea grupo con TODOS los tags que tengan endpoints
}Notas:
- Si definís
autoDocsDir, el generador crea: un grupo por carpeta y un tag por cada.md. - Los tags se conservan aunque no tengan endpoints si aparecen en
keepTags(o sikeepUnusedTags=true). - El grupo automático
APIordena alfabéticamente (case‑insensitive) los modelos con endpoints.
🧠 Metadatos en modelos (x-doc)
En cada common/models/<modelo>.json podés opcionalmente definir:
{
"name": "deposit",
"plural": "deposits",
"x-doc": {
"tagName": "Deposit",
"tagDescription": "Overview del dominio Deposit"
},
"methods": {
"addNewDepositPublic": {
"summary": "Crear depósito",
"http": { "path": "/add-new-deposit-public", "verb": "POST" },
"accepts": [ { "arg": "data", "type": "object", "properties": { /* … */ } } ],
"returns": { "type": "DepositAddResponse", "root": true }
}
}
}El generador:
- Retitula el tag del modelo con
x-doc.tagName(y overview conx-doc.tagDescription). - Re‑etiqueta TODAS las operaciones cuyo path empiece con
/{plural}para que cuelguen del mismo tag. - Usa
summaryodescriptiondel método (o lo “humaniza” si faltan) para el nombre del endpoint.
Para que Redoc muestre un ejemplo de respuesta más útil, definí
returns.typecon un modelo/DTO yroot:true. Si no hay esquema, verás{ data: {} }.
📁 Artefactos generados
Por defecto se escriben en el tmp del sistema ($TMPDIR/openapi-docs-${NODE_ENV}) para evitar reinicios de nodemon:
swagger.jsonswagger-patched.jsonopenapi3.jsonredoc.html
Podés cambiar la carpeta con outputDir.
📝 Buenas prácticas
- Usá
x-doc.tagName/tagDescriptionpara nombrar y describir cada modelo. - Usá
summarypor operación para un menú más legible. - Para contenido libre (guías, conceptos), preferí
autoDocsDir+ archivos.md. - Evitá duplicar títulos H2 idénticos al nombre del tag para que Redoc no repita anclas con el mismo texto.
✅ Requisitos
- Node.js >= 14
- LoopBack 3 con
loopback-swagger
Changelog (resumen de mejoras recientes)
- Filtro por
model-config.*por entorno (oculta métodos/modelos no públicos/no compartidos). x-doc.tagName+ retag por prefijo de path (unifica “User”/“user”).- Ignora RabbitMQ por defecto (se puede re‑habilitar).
api-docs-config.json:infoDescriptionFile,tags[].descriptionFile,autoDocsDir,keepTags,autoGroupRemainingAs.- Orden alfabético del grupo “API”.
- Artefactos en tmp por default (opcional cache por env).
Con ❤️ por quienes todavía mantienen LB3 😄
Guía de desarrollo
Para entender la arquitectura interna, puntos de extensión y el flujo completo de generación/filtrado, ver:
DEVELOPMENT.md
Preview local
- Con servidor Node (ejecuta el pipeline completo del paquete):
node dev/preview.jsAbre: http://localhost:5050/api-docs
- Como archivo estático (solo render de un OAS3 de ejemplo):
- Abre
dev/preview.static.htmldirectamente en el navegador. - Usa
dev/openapi3-sample.json(no prueba generación/patch/convert, solo el render de Redoc).
- Abre
