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:
backend.add(import('@backstage/plugin-catalog-backend'));
backend.add(import('@backstage/plugin-scaffolder-backend'));
backend.add(import('@backstage/plugin-auth-backend'));
backend.add(import('@sazon/plugin-sazon-status-backend'));
|
Qué hace
backend.add(…)Cada |
|
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().
// coreServices are resolved lazily by the framework:
// - DatabaseService -> better-sqlite3 in dev, postgres in prod
// - CacheService -> in-memory in dev, memcached/redis in prod
// - HttpAuthService -> wraps the identity header into a Principal
// - LoggerService -> pino with structured JSON
// - ConfigService -> composes app-config*.yaml layers in order
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.
backend:
database:
client: pg
connection:
host: ${POSTGRES_HOST}
port: ${POSTGRES_PORT}
user: ${POSTGRES_USER}
password: ${POSTGRES_PASSWORD}
cache:
store: redis
connection: ${REDIS_URL}
baseUrl: http://localhost:7007
cors:
origin: http://localhost:3000
|
Buenas prácticas con config
|
Backend features: plugins vs módulos
Una BackendFeature puede ser de tres tipos:
-
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.