Catalog en serio: kinds, relaciones y providers

Objetivos del capítulo
  • Modelar cinco entidades reales: web, API, worker, base de datos y System.

  • Definir relaciones semánticas entre componentes (dependsOn, providesApi, consumesApi).

  • Conectar un provider de descubrimiento desde GitHub.

  • Importar proyectos ya existentes en bloque.

En el :cap-03 cargamos una entidad. Pero una IDP vive o muere según su catálogo: si tiene 5 componentes suecos, no es una IDP, es un monolito. La salsa está en modelar correctamente un conjunto de servicios, sus relaciones y cómo se sincronizan desde las fuentes de verdad.

Ahora poblamos el catálogo con los cinco componentes base de Sazón Foods, definimos cómo se relacionan y los importamos desde GitHub.

Los cinco componentes semilla

Una SaaS B2B de restaurantes tiene, en su forma más simple:

  • Una web (panel para cocineros).

  • Una API que sirve la lógica de negocio.

  • Un worker que ejecuta tareas async (notificaciones, informes).

  • Una base de datos Postgres donde vive el estado.

  • Un System que agrupa los anteriores como una unidad lógica.

Los cinco componentes y su System
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 TB
  System["sazon-restaurant (System)"]
  Web["sazon-web (Component: website)"]
  API["sazon-api (Component: service)"]
  Worker["sazon-worker (Component: service)"]
  DB["sazon-postgres-prod (Resource: database)"]
  System --> Web
  System --> API
  System --> Worker
  System --> DB
  Web -->|consumesApi| API
  Worker -->|consumesApi| API
  API -->|dependsOn| DB

El System es la mise-en-place agrupada: la bandeja con los cinco ingredientes que componen el plato sazon-restaurant. Sin esa bandeja, el cocinero tiene que ir al mercado cada vez.

El catálogo semilla:

Unresolved directive in chapters/cap-04-catalog-en-serio.adoc - include::../../chapters/chapter-04-catalog/entities/seeds.yaml[tag=seeds-five-components]
Qué acabas de hacer
  • Cinco entidades del kind Component y Resource, todas con spec.owner, spec.system apuntando a sazon-restaurant.

  • Una entidad System (lo crearemos a continuación) que las agrupa.

  • El namespace default es la convención por defecto; en producción usa el dominio de tu empresa (ej. acme, sazon-foods).

La entidad System

El System agrupa componentes que comparten dominio. En Backstage se modela como una entidad con kind System. Sus relaciones hasPart lo enlazan con cada componente.

apiVersion: backstage.io/v1alpha1
kind: System
metadata:
  name: sazon-restaurant
  title: Sazón Foods — Restaurante SaaS
  description: Plataforma SaaS B2B para gestión de pedidos en restaurantes.
spec:
  owner: guests
  domain: sazon-foods
  type: saas

Tras guardar el archivo y reiniciar el backend, refresca el catalog: sazon-restaurant aparece como padre de los cinco componentes.

Backstage soporta relaciones entre entidades. Tres relaciones nos llevan lejos:

  • dependsOn: A depende de B (ej. la API depende de la DB).

  • providesApi: A expone una API llamada X (ej. la API provee sazon-orders).

  • consumesApi: A consume una API llamada X (ej. la web consume sazon-orders).

Por qué importan las relaciones

Las relaciones permiten a los plugins renderizar grafos de dependencias (Tech Insights, Catalog Graph) y al Scaffolder razonar sobre qué generar. Una entidad sin relaciones es un nodo aislado en un grafo.

Definimos las relaciones como un YAML de relaciones:

Unresolved directive in chapters/cap-04-catalog-en-serio.adoc - include::../../chapters/chapter-04-catalog/entities/relations.yaml[tag=relations-graph]

Cada relación tiene un source, type y target. La entidad API definida aparte (con metadata.name: sazon-orders-api y spec.type: openapi) es referenciada por las relaciones providesApi/consumesApi.

Providers: discovery automático desde GitHub

Mantener entidades a mano es tedioso. Backstage soporta providers que descubren repos en GitHub y los ingieren como entidades automáticamente.

¿Cómo funciona?

El GithubDiscoveryProcessor escanea una org o un equipo, busca catalog-info.yaml en cada repo, y los ingesta como entidades. Se ejecuta en cada tick configurable.

Activamos el provider desde app-config.addons.yaml:

Unresolved directive in chapters/cap-04-catalog-en-serio.adoc - include::../../chapters/chapter-04-catalog/app-config.addons.yaml[tag=github-discovery-config]
Política de filtros

El filters es clave en producción: sin él, el provider ingesta cualquier repo de la org, incluidos los personales o archivados. Acota el repo:.* y topic:backstage para ingerir solo lo declarado.

Importar proyectos existentes en bloque

Si tienes decenas de repos ya creados y quieres migrarlos de golpe, hay un script de bulk-import. Backstage lo publica como ejemplo y lo hemos adaptado para Sazón Foods:

Unresolved directive in chapters/cap-04-catalog-en-serio.adoc - include::../../chapters/chapter-04-catalog/scripts/import-existing.sh[tag=bulk-import-script]
El flujo del script
  1. Clona cada repo listado en repos.txt.

  2. Si encuentra un catalog-info.yaml, lo deja intacto.

  3. Si no, lo genera con heurísticas (lenguaje detectado, nombre del repo, owner).

  4. Crea un PR en cada repo con el nuevo catalog-info.yaml.

Útil cuando arrancas con muchos servicios ya en producción.

Example 4. Receta del capítulo
  1. Crea los cinco Component y un System.

  2. Añade relaciones dependsOn, providesApi y consumesApi.

  3. Activa el GithubDiscoveryProcessor con un filtro razonable.

  4. Si tienes repos legacy, ejecuta el bulk-import y revisa los PRs.

Resumen

  • Modelar System + Component + relaciones es la base del catalog.

  • Las relaciones permiten grafos, dependencias y razonamiento sobre la topología.

  • El GithubDiscoveryProcessor sincroniza el catalog desde GitHub con filtros.

  • El bulk-import acelera la adopción en empresas con muchos servicios.

Glosario del capítulo

kind

Categoría de entidad (Component, API, Resource, System, Domain, Group, User).

relación

Edge del grafo: dependsOn, providesApi, consumesApi, hasPart, ownerOf.

provider

Componente que descubre entidades en una fuente externa (GitHub, GitLab, etc.).

processor

Pieza que procesa una entidad: enriquece, valida, transforma.

Próximo capítulo

El backend: en qué cocina se cocina —pasamos del catalog al backend: arquitectura, configuración y cómo extenderlo con plugins.

Parte II: Parte 2 — Backend: la cocina por dentro

La New Backend System, los services del core, y nuestro primer plugin backend completo. Aquí es donde la cocina pasa de hobby a restaurante.