examples.ts•8.36 kB
export const examples = {
title: "Backstage Examples and Code Samples",
description: "Practical examples for common Backstage development scenarios",
content: {
pluginExamples: {
basicFrontendPlugin: {
description: "Simple frontend plugin with a custom page",
code: `
// src/plugin.ts
import { createPlugin, createRoutableExtension } from '@backstage/core-plugin-api';
import { rootRouteRef } from './routes';
export const myPlugin = createPlugin({
id: 'my-plugin',
routes: {
root: rootRouteRef,
},
});
export const MyPluginPage = myPlugin.provide(
createRoutableExtension({
name: 'MyPluginPage',
component: () => import('./components/MyPluginPage').then(m => m.MyPluginPage),
mountPoint: rootRouteRef,
}),
);
// src/components/MyPluginPage.tsx
import React from 'react';
import { Page, Header, Content } from '@backstage/core-components';
export const MyPluginPage = () => (
<Page themeId="tool">
<Header title="My Plugin" subtitle="Custom plugin example" />
<Content>
<div>Welcome to my custom plugin!</div>
</Content>
</Page>
);`
},
catalogEntityProvider: {
description: "Custom entity provider for external data sources",
code: `
// src/providers/MyEntityProvider.ts
import { EntityProvider, EntityProviderConnection } from '@backstage/plugin-catalog-backend';
import { Entity } from '@backstage/catalog-model';
export class MyEntityProvider implements EntityProvider {
private readonly env: string;
private connection?: EntityProviderConnection;
constructor(env: string) {
this.env = env;
}
getProviderName(): string {
return \`my-provider-\${this.env}\`;
}
async connect(connection: EntityProviderConnection): Promise<void> {
this.connection = connection;
await this.run();
}
async run(): Promise<void> {
if (!this.connection) {
throw new Error('Not initialized');
}
const entities = await this.fetchEntities();
await this.connection.applyMutation({
type: 'full',
entities: entities.map(entity => ({
locationKey: this.getProviderName(),
entity,
})),
});
}
private async fetchEntities(): Promise<Entity[]> {
// Fetch from external API
return [
{
apiVersion: 'backstage.io/v1alpha1',
kind: 'Component',
metadata: {
name: 'my-service',
namespace: 'default',
},
spec: {
type: 'service',
lifecycle: 'production',
owner: 'team-a',
},
},
];
}
}`
},
scaffolderAction: {
description: "Custom scaffolder action for code generation",
code: `
// src/actions/myAction.ts
import { createTemplateAction } from '@backstage/plugin-scaffolder-backend';
import { z } from 'zod';
export const createMyAction = () => {
return createTemplateAction<{
name: string;
description?: string;
}>({
id: 'my:custom:action',
description: 'Creates a custom file',
schema: {
input: z.object({
name: z.string().describe('Name of the component'),
description: z.string().optional().describe('Description'),
}),
},
async handler(ctx) {
const { name, description } = ctx.input;
await ctx.output('logs', \`Creating component: \${name}\`);
const content = \`
# \${name}
\${description || 'No description provided'}
Generated by custom scaffolder action.
\`;
await ctx.output('file', {
path: \`\${name}/README.md\`,
content,
});
},
});
};`
}
},
catalogExamples: {
componentEntity: {
description: "Example component entity YAML",
code: `
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: my-service
description: A microservice for user management
annotations:
github.com/project-slug: myorg/my-service
backstage.io/techdocs-ref: dir:.
tags:
- nodejs
- microservice
- api
links:
- url: https://my-service.example.com
title: Production
icon: web
- url: https://grafana.example.com/dashboard/my-service
title: Monitoring
icon: dashboard
spec:
type: service
lifecycle: production
owner: team-backend
system: user-management
providesApis:
- user-api
consumesApis:
- auth-api
dependsOn:
- resource:user-database`
},
systemEntity: {
description: "Example system entity YAML",
code: `
apiVersion: backstage.io/v1alpha1
kind: System
metadata:
name: user-management
description: User management system
spec:
owner: team-backend
domain: authentication`
},
apiEntity: {
description: "Example API entity YAML",
code: `
apiVersion: backstage.io/v1alpha1
kind: API
metadata:
name: user-api
description: User management API
spec:
type: openapi
lifecycle: production
owner: team-backend
system: user-management
definition: |
openapi: 3.0.0
info:
title: User API
version: 1.0.0
paths:
/users:
get:
summary: List users
responses:
'200':
description: Successful response`
}
},
templateExamples: {
basicTemplate: {
description: "Basic software template structure",
code: `
# template.yaml
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
name: nodejs-service
title: Node.js Service
description: Create a new Node.js microservice
tags:
- recommended
- nodejs
spec:
owner: platform-team
type: service
parameters:
- title: Fill in some steps
required:
- name
- description
properties:
name:
title: Name
type: string
description: Unique name of the component
pattern: '^([a-z0-9\\-])+$'
description:
title: Description
type: string
description: Help others understand what this service is for
owner:
title: Owner
type: string
description: Owner of the component
ui:field: OwnerPicker
ui:options:
allowedKinds:
- Group
steps:
- id: fetch-base
name: Fetch Base
action: fetch:template
input:
url: ./content
values:
name: \${{ parameters.name }}
description: \${{ parameters.description }}
owner: \${{ parameters.owner }}
- id: publish
name: Publish
action: publish:github
input:
allowedHosts: ['github.com']
description: This is \${{ parameters.name }}
repoUrl: \${{ parameters.repoUrl }}
- id: register
name: Register
action: catalog:register
input:
repoContentsUrl: \${{ steps.publish.output.repoContentsUrl }}
catalogInfoPath: '/catalog-info.yaml'
output:
links:
- title: Repository
url: \${{ steps.publish.output.remoteUrl }}
- title: Open in catalog
icon: catalog
entityRef: \${{ steps.register.output.entityRef }}`
}
},
configExamples: {
appConfig: {
description: "Basic app-config.yaml setup",
code: `
app:
title: My Backstage App
baseUrl: http://localhost:3000
organization:
name: My Company
backend:
baseUrl: http://localhost:7007
listen:
port: 7007
csp:
connect-src: ["'self'", 'http:', 'https:']
cors:
origin: http://localhost:3000
methods: [GET, POST, PUT, DELETE]
credentials: true
database:
client: pg
connection:
host: \${POSTGRES_HOST}
port: \${POSTGRES_PORT}
user: \${POSTGRES_USER}
password: \${POSTGRES_PASSWORD}
integrations:
github:
- host: github.com
token: \${GITHUB_TOKEN}
catalog:
rules:
- allow: [Component, System, API, Resource, Location]
locations:
- type: file
target: ../../examples/entities.yaml
- type: file
target: ../../examples/template/template.yaml
rules:
- allow: [Template]
auth:
providers:
github:
development:
clientId: \${AUTH_GITHUB_CLIENT_ID}
clientSecret: \${AUTH_GITHUB_CLIENT_SECRET}
techdocs:
builder: 'local'
generator:
runIn: 'local'
publisher:
type: 'local'`
}
}
}
};