docs: adding more golden path docs (#32493)

* docs: adding more golden path docs

Signed-off-by: aramissennyeydd <aramis.sennyey@doordash.com>

* cleanup

Signed-off-by: aramissennyeydd <aramis.sennyey@doordash.com>

* add instructions for checking todo list items

Signed-off-by: aramissennyeydd <aramis.sennyey@doordash.com>

* update ids so the number isn't baked into URL

Signed-off-by: aramissennyeydd <aramis.sennyey@doordash.com>

* add headings for all docs

Signed-off-by: aramissennyeydd <aramis.sennyey@doordash.com>

* add frontend plugin docs structure too

Signed-off-by: aramissennyeydd <aramis.sennyey@doordash.com>

* Apply suggestions from code review

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Aramis Sennyey <159921952+aramissennyeydd@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Aramis Sennyey <159921952+aramissennyeydd@users.noreply.github.com>

* fix bad link

Signed-off-by: aramissennyeydd <aramis.sennyey@doordash.com>

* address feedback

Signed-off-by: aramissennyeydd <aramis.sennyey@doordash.com>

* Apply suggestions from code review

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Aramis Sennyey <159921952+aramissennyeydd@users.noreply.github.com>

---------

Signed-off-by: aramissennyeydd <aramis.sennyey@doordash.com>
Signed-off-by: Aramis Sennyey <159921952+aramissennyeydd@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
Aramis Sennyey
2026-02-13 14:20:32 -05:00
committed by GitHub
parent ddd54c755c
commit 8f6bf6b4e7
29 changed files with 541 additions and 54 deletions
+15
View File
@@ -0,0 +1,15 @@
<!-- THIS FILE IS NOT INTENDED TO BE DISPLAYED ON THE DOCSITE -->
## Why build plugins?
This section should clearly explain why you should build a new plugin. The Backstage framework is deeply empowered by plugins and plugins are core to the project's success. Users should walk away from reading this section with a conviction that plugins are the right path for new functionality.
## Sustainable plugin development
Plugins are not developed in a vacuum. Users should reach for them to solve specific business problems facing their developers, for example, you may be tasked to create
- a new vendor integration like PagerDuty,
- a new plugin backend that talks to an internal service,
- etc.
This section should contain learnings from successful Backstage deployments about how to engage with stakeholders, how/when to iterate on your plugin, and setting yourself up for future success.
@@ -1,5 +1,5 @@
---
id: 001-first-steps
id: first-steps
sidebar_label: 001 - Scaffolding the plugin
title: How to scaffold a new plugin?
---
@@ -1,5 +1,5 @@
---
id: 002-poking-around
id: poking-around
sidebar_label: 002 - Poking around
title: 002 - Poking around
---
@@ -16,7 +16,7 @@ To make this plugin production ready, we'll need to adjust a few things,
## Testing locally
Before we jump in to making this plugin ready to ship, let's walk through how to run it locally. If you open your backend plugin's manifest (`plugins/todo-backend/package.json`), and look at the `scripts` section, you'll notice a few important commands. The ones relevant to use right now are
Before we jump in to making this plugin ready to ship, let's walk through how to run it locally. If you open your backend plugin's manifest (`plugins/todo-backend/package.json`), and look at the `scripts` section, you'll notice a few important commands. The ones relevant to us right now are
1. `yarn start` - Starts a local development server using the content in `dev/index.ts` as the backend.
2. `yarn test` - Runs all of the tests for your backend plugin.
@@ -27,8 +27,43 @@ If you run `yarn start`, you should see a custom backend for just your plugin st
2025-06-08T16:14:53.229Z rootHttpRouter info Listening on :7007
```
This indicates that your HTTP server is up and running and we can start sending test HTTP requests. Grab your favorite HTTP client and let's get testing! If you aren't sure what to use, I'd recommend the `humao.rest-client` VSCode extension which can easily be run in VSCode itself with very little extra set up.
This indicates that your HTTP server is up and running and we can start sending test HTTP requests. Grab your favorite HTTP client and let's get testing!
To start, let's make sure we're starting from a clean slate. You can list all existing TODOs by running the command below. You should get back an empty list:
```sh
curl http://localhost:7007/api/todo/todos
```
To create a new TODO, you can send a POST request to the same endpoint. However, you will get a 401 error right now.
```sh
curl -X POST http://localhost:7007/api/todo/todos \
-H 'Content-Type: application/json; charset=utf-8' \
--data-binary @- << EOF
{
"title": "My Todo"
}
EOF
```
The 401 error is because we track the ID of the user that created each TODO. If you send a request to create a TODO but don't provide an `Authorization` header, you will see this failure. For plugins that have a frontend as well, this credential management should happen automatically. Let's try this:
```sh
curl -v -X POST http://localhost:7007/api/todo/todos \
-H 'Content-Type: application/json; charset=utf-8' \
-H "Authorization: Bearer $(curl -s http://localhost:7007/api/auth/guest/refresh | jq -r '.backstageIdentity.token')" \
--data-binary @- << EOF
{
"title": "My Todo"
}
EOF
```
We can then list all TODOs to see our new TODO!
```sh
curl http://localhost:7007/api/todo/todos
```
You'll notice that `createdBy` is `user:development/guest` which is the token we used to create the TODO. That's the `-H "Authorization: Bearer $(curl -s http://localhost:7007/api/auth/guest/refresh | jq -r '.backstageIdentity.token')"` part of the request.
@@ -0,0 +1,19 @@
---
id: persistence
sidebar_label: 003 - Persisting your TODOs
title: 003 - Persisting your TODOs
---
## Saving Plugin State Indefinitely
You may have noticed that your list of TODOs disappears after you restart your Backstage backend. The general flow to restart your backend without having to rerun `yarn start` is to press ENTER on the terminal running `yarn start`. This will force the Backstage backend to restart completely, wiping out any in memory data and starting everything from scratch -- everything except your database.
### Quick intro to SQLite
SQLite is the default database for local development. It runs in memory (and can also run from a file on disk). It supports quick iteration cycles and can be easily deleted if anything goes wrong.
## Adding the `databaseService` to your plugin
<!--TODO-->
## Testing your changes
@@ -0,0 +1,19 @@
---
id: source-tracked
sidebar_label: 004 - Integrating with SCMs
title: 004 - Git-tracked TODOs
---
Problem: You have TODOs in your source code that you want to ingest with your plugin.
## Authenticating
<!--TODO-->
## Querying
<!--TODO-->
## Fetching
<!--TODO-->
@@ -0,0 +1,29 @@
---
id: testing
sidebar_label: 005 - Unit testing your plugin
title: 005 - Testing
---
## Testing is important
We've done a lot of manual testing up to this point of functionality. Let's start putting those assumptions into code that we can run on every change to ensure things are working correctly.
## Router-level testing
<!--TODO-->
## Plugin-level testing
<!--TODO-->
## OpenAPI testing
<!--TODO-->
### Integration with Jest tests
<!--TODO-->
### Fuzzing
<!--TODO-->
+4 -35
View File
@@ -1,36 +1,7 @@
<!-- THIS FILE IS NOT INTENDED TO BE DISPLAYED ON THE DOCSITE -->
# Glossary
- Page: A single `md` file.
- Guide: A number of pages grouped under the same folder.
# Overall Writing Guidelines
The goal of these docs is to provide a comprehensive set of guides that developers + admins can use to quickly get up to speed with plugin development, and then refer to as they're developing their own plugins.
A user that finishes all of these guides will feel comfortable implementing plugins on their own. If additional assistance is required, they should be referred to other sources of information such as Discord, GitHub, source code, or documentation for further support. The user will also understand why/when to build their own plugins, inner-sourcing their developer portal and contributing internal plugins back to the open-source project.
At the same time, not all users will finish the docs or they may come back to them as required. Individual guides should have strong "abstracts" (what will I learn by reading this guide), table of contents, and "next steps" (what do I need to do next) to guide users to read the most important pieces for their work.
When writing guide pages, keep it light! These should be instructional docs, and at the same time conversational and a joy to read. Guides should build on each other, when reading through a progression, the reader should feel more comfortable and confident with concepts as they pop up across progression levels. Guides should be standalone, when finishing one level (for example 101), you should be able to immediately jump into the next (201) without additional research or background. Referencing previous progression levels is ok.
# Sections
## Why build plugins?
This section should answer definitely why you should build a new plugin. The Backstage framework is deeply empowered by plugins and plugins are core to the project's success. Users should walk away from reading this section with a conviction that plugins are the right path for new functionality.
## Sustainable plugin development
Plugins are not developed in a vacuum. Users should reach for them to solve specific business problems facing their developers, for example, you may be tasked to create
- a new vendor integration like PagerDuty,
- a new plugin backend that talks to an internal service,
- etc.
This section should contain learnings from successful Backstage deployments about how to engage with stakeholders, how/when to iterate on your plugin, and setting yourself up for future success.
## Creating your first plugin
This section should be extremely deliberate in showing readers every step of the way to create a plugin using Backstage's best practices. A reader that finishes this section should feel extremely comfortable creating new plugins and how to install and use plugins regardless of their experience with JS/TS and Backstage.
@@ -78,12 +49,6 @@ app.get('/list', async (req, res) => {
});
```
### Testing
Let's write a unit test using `supertest` to make sure that everything is working as expected.
After verifying everything, introduce the problem of persistence - the todos aren't saved across reloads.
### Persistence
Saving values to the database. Writing a migrations file. Plumbing through the database service.
@@ -91,3 +56,7 @@ Saving values to the database. Writing a migrations file. Plumbing through the d
## SCM Integrations
Our users love the new plugin, and now they want it to automatically fetch todos from their source code.
### Testing
Let's write a unit test using `supertest` to make sure that everything is working as expected.
@@ -1,12 +0,0 @@
POST http://localhost:7007/api/todo/todos
Content-Type: application/json
{
"title": "My First TODO"
}
###
GET http://localhost:7007/api/todo/todos
###
@@ -0,0 +1,15 @@
---
id: first-steps
sidebar_label: 001 - Scaffolding the plugin
title: How to scaffold a new plugin?
---
Running `yarn new` -> `frontend-plugin`.
## What did we create?
<!--TODO-->
## Common issues
<!--TODO-->
@@ -0,0 +1,17 @@
---
id: poking-around
sidebar_label: 002 - Poking around
title: 002 - Poking around
---
Our frontend TODO plugin is a bit more simplistic than the backend one. We need to implement a new UI to replace the example components we have.
Let's use this React component to start. Copy this to `plugins/todo/src/components/TodoList.tsx`.
```tsx
// todo
```
### Data Mocking
You already have a backend with dynamic data. Let's start a little smaller. Using hard coded data can be a great way to iterate quickly.
@@ -0,0 +1,29 @@
---
id: dynamic-config
sidebar_label: 003 - Dynamic Config
title: 003 - Dynamic Config
---
Your plugin should have been generated by default for the New Frontend System which is config-first. That means you can easily control your frontend components through your `app-config.yaml`.
Let's try this quickly by disabling our entire TODO page,
```yaml
# TODO
```
We can also do really cool things like provide React props directly through config. Let's try moving our hard coded list of TODOs to config instead,
```tsx
// todo
```
and the config,
```yaml
# TODO
```
### Why does this work?
<!--TODO-->
@@ -0,0 +1,17 @@
---
id: http-client
sidebar_label: 004 - HTTP Client
title: 004 - HTTP Client
---
Now, let's really make our page dynamic. We'll start by writing an HTTP client by hand.
```tsx
class TodoClient {
// TODO
}
```
## OpenAPI Generated Clients
You can also skip a step and ensure your frontend and backend stay in sync by generating the client from an OpenAPI schema.
@@ -0,0 +1,15 @@
---
id: testing
sidebar_label: 005 - Testing
title: 005 - Testing
---
Everyone's favorite part! Let's make sure our components continue to work even when we're not able to validate the changes.
## Unit Tests
Use Jest + RTL + MSW v2.
## Integration Tests
Use Playwright.
@@ -0,0 +1,34 @@
<!-- THIS FILE IS NOT INTENDED TO BE DISPLAYED ON THE DOCSITE -->
# Sections
## Creating your first plugin
### Scaffolding a new plugin
Talk through how to run the `backstage-cli create` command as well as what the output it creates is. This should touch on why we install this into `packages/app`.
### Debugging
How to handle common errors.
## First steps with the new plugin
### Creating a todo plugin
We're going to be creating the frontend for a todo list plugin. We want the user to be able to create todos for themselves and show the user their current list of todos.
To start, we'll use a list of mocked data.
### Controlling your component dynamically
Update the mocked data to be controlled by config.
### HTTP API
We want our todo plugin to reach the backend that we implemented in [the backend plugin Golden Path](../backend/001-first-steps.md). Let's write a client to do this (or use OpenAPI to generate a client for us).
### Testing
Unit tests - Let's write a unit test using React Testing Library to make sure that everything is working as expected.
Integration tests - Let's write an integration test using Playwright to _really_ make sure everything is working.
@@ -0,0 +1,23 @@
---
id: catalog
sidebar_label: 001 - Catalog
title: Integrating with Catalog
---
## Software Catalog
### What is the Software Catalog?
<!--TODO-->
### Integration Points
<!--TODO-->
## Adding a new `backstage.io/todo` annotation
<!--TODO-->
## Custom TODO Entity Kind
<!--TODO-->
@@ -0,0 +1,19 @@
---
id: search
sidebar_label: 002 - Search
title: Integrating with Search
---
## Search
### What is Backstage Search?
<!--TODO-->
### Common integration points
<!--TODO-->
## Creating a custom TODO collator
<!--TODO-->
@@ -0,0 +1,23 @@
---
id: permissions
sidebar_label: 003 - Permissions
title: Integrating with the Permission framework
---
## Permissions
### What is the Permissions framework?
<!--TODO-->
### Common integration points
<!--TODO-->
## Creating private TODOs
<!--TODO-->
## Restricting who can create TODOs
<!--TODO-->
@@ -0,0 +1,23 @@
---
id: notifications
sidebar_label: 004 - Notifications
title: Integrating with Notifications
---
## Notifications
### What are Backstage Notifications?
<!--TODO-->
### Common integration points
<!--TODO-->
## TODO with an alarm
<!--TODO-->
## Create TODOs for other people and notify them
<!--TODO-->