Skip to main content

PLAN-004: Backstage API Entities

IMPLEMENTATION RULES: Before implementing this plan, read and follow:

Status: Complete

Goal: Add API entities to the Backstage catalog so that services show "Provided APIs" and "Consumed APIs" tabs with dependency relationships

Last Updated: 2026-03-13

Investigation: INVESTIGATE-backstage-enhancements.md — Enhancement 1

Prerequisites: PLAN-002 complete (Backstage deployed with catalog)


Overview

The Backstage catalog currently has Components and Resources linked via dependsOn. This plan adds kind: API entities so developers can see which services provide and consume APIs. The dependency graph becomes richer — showing actual integration boundaries, not just infrastructure dependencies.

Scope: Text descriptions only for API definitions. No OpenAPI spec URLs — that's a future enhancement when we build our own integrations with openapi.yaml files in repos.

Service definition field schema: provision-host/uis/schemas/service.schema.json — single source of truth for all field definitions.


Phase 1: Add New Fields to Service Definitions

Tasks

  • 1.1 Add SCRIPT_PROVIDES_APIS and SCRIPT_CONSUMES_APIS to provision-host/uis/schemas/service.schema.json
  • 1.2 Add fields to service definitions that provide APIs
  • 1.3 Add fields to service definitions that consume APIs
  • 1.4 Update docs files to match schema (adding-a-service.md, naming-conventions.md, kubernetes-deployment.md)

Implementation Details

New fields:

# === Extended Metadata (Optional) ===
SCRIPT_PROVIDES_APIS="" # space-separated: "litellm-api"
SCRIPT_CONSUMES_APIS="" # space-separated: "litellm-api"

Services that provide APIs:

ServiceSCRIPT_PROVIDES_APISAPI Description
litellmlitellm-apiOpenAI-compatible LLM proxy REST API
authentikauthentik-apiIdentity provider OAuth/OIDC/SAML API
openmetadataopenmetadata-apiData governance and metadata REST API
graviteegravitee-apiAPI management and gateway REST API
grafanagrafana-apiDashboard and datasource query REST API
tikatika-apiDocument text extraction REST API
openwebuiopenwebui-apiAI chat web interface and REST API

Services that consume APIs:

ServiceSCRIPT_CONSUMES_APIS
openwebuilitellm-api

Note: Most services consume database Resources (already modeled via dependsOn). Only model explicit API consumption where it adds clarity — not every HTTP call needs an API entity.

Validation

  • Schema validates with new fields
  • Service definitions have correct field values

Phase 2: Update Catalog Generator

Tasks

  • 2.1 Extract SCRIPT_PROVIDES_APIS and SCRIPT_CONSUMES_APIS in extract_all_metadata()
  • 2.2 Add providesApis and consumesApis to generate_service_entity() spec section
  • 2.3 Create generate_api_entity() function for kind: API entities
  • 2.4 Update generate_all_yaml() to include API entity references
  • 2.5 Update static entity for tika to include providesApis

Implementation Details

API entity generation approach:

  • API registry collects metadata from all services during scanning
  • Each unique API name generates one kind: API entity
  • spec.type is description (not openapi — avoids renderer error since definitions are text)
  • API entities inherit K8s annotations (namespace, label-selector) from parent service
  • Tika API registered as a static entry alongside its static component

Example generated API entity (litellm-api):

apiVersion: backstage.io/v1alpha1
kind: API
metadata:
name: litellm-api
description: "Unified API gateway for LLM providers"
annotations:
backstage.io/techdocs-ref: url:https://uis.sovereignsky.no/docs/services/ai/litellm
backstage.io/kubernetes-namespace: ai
backstage.io/kubernetes-label-selector: "app.kubernetes.io/name=litellm"
uis.sovereignsky.no/docs-url: "https://uis.sovereignsky.no/docs/services/ai/litellm"
links:
- url: https://uis.sovereignsky.no/docs/services/ai/litellm
title: "litellm-api Docs"
icon: docs
spec:
type: description
lifecycle: production
owner: app-team
system: ai
definition: "Unified API gateway for LLM providers"

Updated Component entity (litellm):

spec:
type: service
lifecycle: production
owner: app-team
system: ai
providesApis:
- litellm-api
dependsOn:
- resource:postgresql

Updated Component entity (openwebui):

spec:
type: service
lifecycle: production
owner: app-team
system: ai
providesApis:
- openwebui-api
consumesApis:
- litellm-api
dependsOn:
- resource:postgresql

Validation

  • ./uis catalog generate completes without errors
  • Generated API entity files appear in generated/backstage/catalog/apis/
  • Generated component files include providesApis/consumesApis where appropriate
  • all.yaml references the new API entity files

Phase 3: Deploy and Verify

Tasks

  • 3.1 Build container with updated generator
  • 3.2 Regenerate catalog: ./uis catalog generate
  • 3.3 Redeploy backstage: ./uis undeploy backstage && ./uis deploy backstage
  • 3.4 Verify in browser: check litellm entity page → "Provided APIs" tab shows litellm-api
  • 3.5 Verify in browser: check openwebui entity page → "Consumed APIs" tab shows litellm-api
  • 3.6 Verify in browser: check litellm-api entity page → shows provider and consumer
  • 3.7 Verify dependency graph shows API relationships

Validation

  • API entities visible in Backstage catalog (7 entities at /api-docs)
  • Provided/Consumed APIs tabs populated on component pages
  • Dependency graph includes API relationships

Issues found and fixed during testing

  1. API page URL: Backstage uses /api-docs not /apis for the API list page
  2. Definition tab rendering: Changed spec.type from openapi to description to avoid OpenAPI renderer error on text definitions
  3. K8s annotations on API entities: Added namespace and label-selector inheritance from parent service to fix "Missing Annotation" on API entity Kubernetes tabs

Phase 4: Cleanup

Tasks

  • 4.1 Update INVESTIGATE-backstage-enhancements.md — note Enhancement 1 is complete
  • 4.2 Move this plan to completed/

Acceptance Criteria

  • SCRIPT_PROVIDES_APIS and SCRIPT_CONSUMES_APIS fields added to schema and relevant service definitions
  • Catalog generator produces kind: API entities with text descriptions
  • Component entities include providesApis/consumesApis in spec
  • API relationships visible in Backstage UI (tabs and dependency graph)
  • Docs files updated to match schema

Files Modified

FileChange
provision-host/uis/schemas/service.schema.jsonAdded providesApis and consumesApis fields
provision-host/uis/manage/uis-backstage-catalog.shExtract new fields, providesApis/consumesApis in spec, generate_api_entities() with K8s annotation inheritance
provision-host/uis/services/ai/service-litellm.shAdded SCRIPT_PROVIDES_APIS="litellm-api"
provision-host/uis/services/ai/service-openwebui.shAdded SCRIPT_PROVIDES_APIS="openwebui-api" and SCRIPT_CONSUMES_APIS="litellm-api"
provision-host/uis/services/identity/service-authentik.shAdded SCRIPT_PROVIDES_APIS="authentik-api"
provision-host/uis/services/analytics/service-openmetadata.shAdded SCRIPT_PROVIDES_APIS="openmetadata-api"
provision-host/uis/services/integration/service-gravitee.shAdded SCRIPT_PROVIDES_APIS="gravitee-api"
provision-host/uis/services/observability/service-grafana.shAdded SCRIPT_PROVIDES_APIS="grafana-api"
website/docs/contributors/guides/adding-a-service.mdAdded new fields to example and reference table
website/docs/contributors/rules/naming-conventions.mdAdded new fields to example
website/docs/contributors/rules/kubernetes-deployment.mdAdded new fields to example and metadata groups table