mcpField
U
using-backstage-backend-services

using-backstage-backend-services

github.com/vinzscamDevelopment446 installsUpdated 9w ago
Repository

About using-backstage-backend-services

A skill for developers building or modifying Backstage backend plugins and modules. It helps select the appropriate core service and apply its usage patterns, including common implementation and testing pitfalls.

Key features

  1. 01Guidance for selecting core services
  2. 02Plugin and module service patterns
  3. 03Auth and cross-plugin HTTP guidance
  4. 04Scheduling and lifecycle practices
  5. 05Testing with mock services

Use cases

  1. 01Choosing services for a backend feature
  2. 02Adding dependencies to plugin registration
  3. 03Calling another plugin over HTTP
  4. 04Writing backend service tests

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/vinzscam/backstage-skills --skill using-backstage-backend-services

After installing, type/using-backstage-backend-servicesin Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

references/
auth.md
cache.md
database.md
http-router.md
logger-and-config.md
scheduler-and-lifecycle.md
urlReader-and-discovery.md

Details

From the project README

Backstage Backend Services

When to use this skill

  • Plugin or module needs logging, configuration, HTTP routing, database, scheduling, caching, URL fetching, service discovery, or auth
  • User mentions any specific coreServices.* ref
  • Adding a new dep to a register({ deps: {...} }) block

Choose the right service

NeedServiceReference
LoggingcoreServices.logger (plugin-scoped, pre-tagged with pluginId)references/logger-and-config.md
Read app-config.yamlcoreServices.rootConfigreferences/logger-and-config.md
Register HTTP routescoreServices.httpRouterreferences/http-router.md
Knex DB accesscoreServices.database (plugin-scoped, isolated schema)references/database.md
Periodic / cron taskscoreServices.schedulerreferences/scheduler-and-lifecycle.md
Startup / shutdown hookscoreServices.lifecycle (plugin) or coreServices.rootLifecycle (root)references/scheduler-and-lifecycle.md
Service-to-service tokenscoreServices.authreferences/auth.md
Authenticate incoming requestscoreServices.httpAuthreferences/auth.md
Resolve current user from credentialscoreServices.userInforeferences/auth.md
Read external URLs (GitHub, GitLab, etc.)coreServices.urlReaderreferences/urlReader-and-discovery.md
Resolve a backend plugin's base URLcoreServices.discoveryreferences/urlReader-and-discovery.md
Key-value cachecoreServices.cachereferences/cache.md

Two invocation modes

  • Standalone: adding a service dep to an existing plugin or module.
  • Post-scaffold (called by creating-backstage-plugin for backend templates): include coreServices.logger and coreServices.httpRouter as defaults; surface additional services if intent suggests them (e.g. "stores X" → database; "polls every N minutes" → scheduler).

Common gotchas

  • All refs come from @backstage/backend-plugin-api. The actual implementations come from @backstage/backend-defaults, but plugins consume the refs only.
  • Plugin-scoped services give each plugin an isolated instance — coreServices.database returns a Knex client scoped to a per-plugin schema; coreServices.logger is pre-tagged with pluginId. Don't try to share a Knex instance across plugins by passing it around — call cross-plugin via coreServices.discovery + HTTP instead.
  • The auth, httpAuth, and userInfo services are easy to confuse. auth mints/verifies tokens for service-to-service calls; httpAuth authenticates an incoming Express request; userInfo resolves a user identity from credentials returned by httpAuth.
  • coreServices.scheduler schedules durable tasks across replicas — don't use setInterval for production tasks.
  • For tests: use mockServices.<name>(...) to get an instance for unit tests; use mockServices.<name>.factory(...) when passing to startTestBackend({ features: [...] }). Not every service has a factory — httpRouter, cache, urlReader, lifecycle are typically provided by the test backend's defaults.
  • When calling another Backstage plugin via discovery + auth (cross-plugin HTTP), handle non-OK responses with throw await ResponseError.fromResponse(response) from @backstage/errors. It parses the response body for structured error info and produces a typed error other Backstage layers (logging, error reporting, frontend <ResponseErrorPanel>) understand. Never just throw new Error(\Failed: ${response.status}`)`.
  • Inside route handlers, throw typed errors from @backstage/errors (NotFoundError, InputError, NotAllowedError, ConflictError, ServiceUnavailableError, ForwardedError, etc.) — the default backend error middleware turns them into properly-formatted HTTP responses. Don't res.status(...).json(...) for error cases. See references/http-router.md.

Comments

Markdown supported