New Backend System: la cocina real
|
Objetivos del capítulo
|
Más allá del index.ts legacy
En el :cap-02 vimos la cocina desde fuera. Ahora abrimos la puerta de servicio y nos ponemos el delantal: el index.ts ya no se llena de routers, sino de líneas backend.add(import('…')). Cada línea es una receta que la cocina monta al arrancar.
La New Backend System es la arquitectura recomendada desde Backstage 1.20. Sustituye al legacy index.ts con routers manuales por una API limpia basada en createBackend() y BackendFeature.
createBackend y backend features
El archivo de entrada del backend es minimalista:
Unresolved directive in chapters/cap-05-new-backend-system.adoc - include::../../chapters/chapter-05-backend-system/packages/backend/src/index.ts[tag=backend-ts]
|
Qué hace
backend.add(…)Cada |
Failed to generate image: Could not find the 'mmdc' executable in PATH; add it to the PATH or specify its location using the 'mmdc' document attribute sequenceDiagram participant index as index.ts participant backend as createBackend() participant feature as BackendFeature participant services as coreServices index->>backend: createBackend() backend->>backend: register default features backend->>feature: catalogPlugin() backend->>feature: scaffolderPlugin() backend->>feature: authPlugin() backend->>feature: customPlugin() backend->>services: resolve services backend->>index: start() index->>index: http.listen(7007)
|
Diferencia con la legacy
Legacy: montas routers en |
Servicios core
El backend expone un bus de servicios llamado coreServices. Cada feature pide los que necesita y el framework los inyecta. Los servicios clave son:
-
DatabaseService — Knex configurado para Postgres en prod, SQLite en dev.
-
CacheService — backend de cache (in-memory en dev, redis en prod).
-
HttpAuthService — convierte el header de identidad en un Principal.
-
LoggerService — pino con JSON estructurado.
-
ConfigService — expone la configuración fusionada por capas.
-
HttpRouterService — router Express compartido donde los plugins montan sus endpoints.
-
SchedulerService — tareas programadas.
-
DiscoveryService — endpoints internos (catalog, auth, scaffolder).
El framework los resuelve por tipo: tu plugin declara deps: { logger: coreServices.logger } y el backend pasa la implementación correcta en init().
Unresolved directive in chapters/cap-05-new-backend-system.adoc - include::../../chapters/chapter-05-backend-system/packages/backend/src/index.ts[tag=services-resolution]
Configuración por capas
Backstage carga la configuración desde varios archivos YAML en este orden:
-
app-config.yaml— base, en git. -
app-config.local.yaml— overrides locales del developer, gitignored. -
app-config.production.yaml— overrides para producción, segúnNODE_ENV.
Las claves se fusionan con deep merge: la última capa gana en claves hoja, los mapas y arrays se concatenan selectivamente.
Unresolved directive in chapters/cap-05-new-backend-system.adoc - include::../../chapters/chapter-05-backend-system/packages/backend/config/app-config.yaml[tag=layered-config]
|
Buenas prácticas con config
|
Backend features: plugins vs módulos
Una BackendFeature puede ser de tres tipos:
Failed to generate image: Could not find the 'mmdc' executable in PATH; add it to the PATH or specify its location using the 'mmdc' document attribute flowchart LR Plugin["createBackendPlugin"] --> Router[HttpRouter] Module["createBackendModule"] --> Plugin Service["createServiceFactory"] --> Plugin
-
Plugin —
createBackendPlugin({ id, register(env) }). Define un endpoint nuevo (ej. scaffolder). -
Module —
createBackendModule({ pluginId, register(env) }). Añade comportamiento a un plugin existente (ej. un processor del catalog). -
Service factory —
createServiceFactory({ service, factory }). Define un servicio core customizado.
-
Sustituye el
index.tslegacy por uno que usecreateBackend(). -
Añade cada plugin como
backend.add(import('…')). -
Lee la configuración desde el service, no desde variables de entorno sueltas.
-
Si necesitas un plugin existente con cambios, escribe un módulo en lugar de forkear.
Migración desde legacy
La legacy backend system sigue operativa en Backstage 1.x, pero el blog oficial la recomienda como puente temporal. La migración se hace así:
-
Reescribe
index.tspara usarcreateBackend(). -
Convierte cada
createPlugin({ router })acreateBackendPlugin({ id, register }). -
Si tenías routers custom, móntalos con
httpRouter.use(await createRouter(…))dentro de un plugin. -
Borra el archivo legacy una vez arrancada la nueva cocina.
El :apéndice H entra en detalle.
Resumen
-
La New Backend System es la arquitectura por defecto desde 1.20.
-
createBackend()+backend.add(feature)reemplaza el legacyindex.ts. -
Los
coreServicesresuelven dependencias por tipo. -
La configuración se compone por capas (base + local + producción).
Glosario del capítulo
- BackendFeature
-
Unidad que la cocina monta: plugin, módulo o service factory.
- coreServices
-
Bus de servicios resueltos por tipo (Database, Cache, Auth, Logger, etc.).
- config layers
-
Archivos app-config*.yaml que se fusionan en orden.
- HttpRouterService
-
Servicio que expone el router HTTP compartido.
- HttpAuthService
-
Servicio que convierte credenciales HTTP en Principal.
Próximo capítulo
Escribe tu primer plugin backend —de la teoría al primer createBackendPlugin() con router Zod y tests con supertest.