Skip to content

Commit aa41939

Browse files
committed
add some notes on backstage plugins and TAP
1 parent 8eb19e6 commit aa41939

File tree

8 files changed

+2241
-5
lines changed

8 files changed

+2241
-5
lines changed
Lines changed: 362 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,362 @@
1+
---
2+
tags:
3+
- IDP
4+
- Platform Engineering
5+
- Backstage
6+
- Plugin
7+
---
8+
9+
title: Create Backstage Backend Plugin
10+
description: Create Backstage Backend Plugin
11+
12+
# Create Backstage Backend Plugin
13+
14+
Let's start with creating Backstage Backend Plugin.
15+
16+
I'm going to write how I created my plugin.
17+
This is based on the official guide and a Medium blog post (series).
18+
So, this is not something I invented and there likely isn't anything new here.
19+
20+
The idea here is that I write down my experience to serve as my long term memory.
21+
22+
The prior art are these two resources:
23+
24+
* [Backstage Docs - Create a Backend plugin](https://backstage.io/docs/plugins/backend-plugin/)
25+
* [John Tucker (Medium) - Backstage Plugins by Example - Part 2](https://john-tucker.medium.com/backstage-plugins-by-example-part-2-6ead20cb4c8d)
26+
27+
## Steps
28+
29+
The steps we'll take, are the following:
30+
31+
1. Initialize a new backend plugin with Yarn
32+
1. Embed the plugin in our Backstage copy
33+
1. Verify the plugin works within Backstage
34+
1. Build and publish it as a standalone NPMJS package
35+
36+
## Init Backend Plugin
37+
38+
To get started, get to your Backstage code copy.
39+
Make sure you're at the root of the code base.
40+
41+
42+
!!! Example
43+
The root directly should be like this:
44+
45+
```sh
46+
tree -L 1
47+
```
48+
49+
```sh
50+
.
51+
├── README.md
52+
├── app-config.local.yaml
53+
├── app-config.production.yaml
54+
├── app-config.yaml
55+
├── backstage.json
56+
├── catalog-info.yaml
57+
├── dist-types
58+
├── environment.sh
59+
├── examples
60+
├── lerna.json
61+
├── node_modules
62+
├── package.json
63+
├── packages
64+
├── playwright.config.ts
65+
├── plugins
66+
├── tsconfig.json
67+
└── yarn.lock
68+
```
69+
70+
!!! Warning inline end "Name of plugin"
71+
72+
The creation command adds `-backend` automatically.
73+
74+
To create the plugin, we run the `yarn new` command:
75+
76+
```sh
77+
yarn new --select backend-plugin
78+
```
79+
80+
This generates your plugin, which is now located in the folder `./plugins/<nameOfPlugin>`.
81+
82+
The initial response should be something like this:
83+
84+
```sh
85+
Creating backend plugin @internal/plugin-hello-backend
86+
87+
Checking Prerequisites:
88+
availability plugins/hello-backend ✔
89+
creating temp dir ✔
90+
91+
Executing Template:
92+
copying .eslintrc.js ✔
93+
templating README.md.hbs ✔
94+
templating package.json.hbs ✔
95+
copying setupTests.ts ✔
96+
copying index.ts ✔
97+
templating run.ts.hbs ✔
98+
copying router.test.ts ✔
99+
copying router.ts ✔
100+
templating standaloneServer.ts.hbs ✔
101+
102+
Installing:
103+
moving plugins/hello-backend ✔
104+
backend adding dependency ✔
105+
executing yarn install // this will be "working for some time"
106+
executing yarn lint --fix ✔
107+
108+
🎉 Successfully created backend-plugin
109+
```
110+
111+
I've named my plugin Hello, but feel free to choose a different name:
112+
113+
```sh
114+
export PLUGIN_NAME=hello
115+
```
116+
117+
Enter to your plugin directory:
118+
119+
```sh
120+
cd plugins/${PLUGIN_NAME}-backend
121+
```
122+
123+
And then run the self-run command as follows:
124+
125+
```sh
126+
LEGACY_BACKEND_START=true yarn start
127+
```
128+
129+
A successful launch emits the following:
130+
131+
```sh
132+
Build succeeded
133+
2024-01-10T17:06:52.173Z backstage info Listening on :7007
134+
```
135+
136+
This will bootup a Node backend server with your plugin.
137+
To verify your plugin works, run the following:
138+
139+
=== "Httpie"
140+
```sh
141+
http :7007/${PLUGIN_NAME}/health
142+
```
143+
144+
=== "Curl"
145+
```sh
146+
curl http://localhost:7007/${PLUGIN_NAME}/health | jq
147+
```
148+
149+
The response should be a 200 OK with a bit of JSON:
150+
151+
```json
152+
{
153+
"status": "ok"
154+
}
155+
```
156+
157+
## Verify in Backstage
158+
159+
Oke, so the plugin works in and by itself.
160+
161+
That is not very useful, so let's import it into Backstage.
162+
163+
!!! Important "Set Package Namespace"
164+
165+
Before we continue, we should update the Package _namespace_ in `package.json`.
166+
167+
By default, it is `"name": "@internal/...",`.
168+
169+
When we publish it to NPMJS.org we need to set this to our username or organization.
170+
171+
We use this full name (namespace + package name) to import our plugin to Backstage.
172+
So update it now to your username or organization, to avoid problems later.
173+
174+
In my case, the first three lines of `package.json` now look like this:
175+
176+
```json
177+
{
178+
"name": "@kearos/plugin-hello",
179+
"version": "0.2.0",
180+
...
181+
}
182+
```
183+
184+
To make this next command easier to use, export your NPMJS name(space):
185+
186+
```sh
187+
export NPMJS_NAME=
188+
```
189+
190+
Go back to the root directory of Backstage (should be `cd ../../`).
191+
192+
And then run this:
193+
194+
=== "Yarn 1.x"
195+
```sh
196+
yarn add --cwd packages/backend "@${NPMJS_NAME}/plugin-${PLUGIN_NAME}-backend@^0.1.0"
197+
```
198+
199+
=== "Yarn 4.x"
200+
```sh
201+
yarn workspace backend add "@${NPMJS_NAME}/plugin-${PLUGIN_NAME}-backend@^0.1.0"
202+
```
203+
204+
We need to make two more code changes before we can run Backstage and see our plugin live.
205+
206+
First, create a plugin file at `./packages/backend/src/pugins/<name_of_plugin>.ts`:
207+
208+
!!! Example "hello.ts"
209+
210+
```typescript title="./packages/backend/src/pugins/hello.ts"
211+
import { createRouter } from '@kearos/plugin-hello-backend';
212+
import { Router } from 'express';
213+
import { PluginEnvironment } from '../types';
214+
215+
export default async function createPlugin(
216+
env: PluginEnvironment,
217+
): Promise<Router> {
218+
219+
return await createRouter({
220+
logger: env.logger,
221+
});
222+
}
223+
```
224+
225+
Start the Backstage backend:
226+
227+
```sh
228+
yarn start-backend
229+
```
230+
231+
And then call our plugin API again:
232+
233+
=== "Httpie"
234+
```sh
235+
http :7007/api/${PLUGIN_NAME}/health
236+
```
237+
238+
=== "Curl"
239+
```sh
240+
curl localhost:7007/api/${PLUGIN_NAME}/health | jq
241+
```
242+
243+
!!! Warning
244+
Notice the addition of `/api` there.
245+
246+
Which should return the same response:
247+
248+
```json
249+
{
250+
"status": "ok"
251+
}
252+
```
253+
254+
This is it for our Backend plugin code.
255+
256+
While we could implement some logic and create an additional end point,
257+
for the purpose of having a backend and client plugin working together, this is enough.
258+
259+
## Build and Publish to NPMSJS
260+
261+
Before we can wrap it up entirely, we need to publish our backend plugin.
262+
263+
To do so, we need to compile the TypeScript and build a NPM package we can publish.
264+
265+
### Build Package
266+
267+
To compile the type script, we go to the root of the Backstage project, and run the following:
268+
269+
```sh
270+
yarn install && yarn tsc
271+
```
272+
273+
If there are any errors, which there shouldn't, resolve them before continuing.
274+
275+
We can then build the package.
276+
First, go back to the plugin folder:
277+
278+
```sh
279+
cd plugins/${PLUGIN_NAME}-backend
280+
```
281+
282+
Then run the build:
283+
284+
```sh
285+
yarn build
286+
```
287+
288+
Once this is done, your plugin should be build and contain a `dist` folder:
289+
290+
```sh
291+
tree
292+
```
293+
294+
Which gives this result:
295+
296+
```sh
297+
.
298+
├── README.md
299+
├── dist
300+
│   ├── index.cjs.js
301+
│   ├── index.cjs.js.map
302+
│   └── index.d.ts
303+
├── node_modules
304+
├── package.json
305+
└── src
306+
├── index.ts
307+
├── run.ts
308+
├── service
309+
│   ├── router.test.ts
310+
│   ├── router.ts
311+
│   └── standaloneServer.ts
312+
└── setupTests.ts
313+
```
314+
315+
### Publish Package
316+
317+
Ensure you have an NPMJS.org account and your NPM CLI is logged in:
318+
319+
```sh
320+
npm login
321+
```
322+
323+
Then, from the root of your plugin, run the NPM Publish command:
324+
325+
```sh
326+
npm publish --access public
327+
```
328+
329+
Which should ask you to login to your NPM account:
330+
331+
```sh
332+
npm notice
333+
npm notice 📦 @kearos/plugin-hello-backend@0.2.1
334+
npm notice === Tarball Contents ===
335+
npm notice 638B README.md
336+
npm notice 888B dist/index.cjs.js
337+
npm notice 1.2kB dist/index.cjs.js.map
338+
npm notice 235B dist/index.d.ts
339+
npm notice 1.1kB package.json
340+
npm notice === Tarball Details ===
341+
npm notice name: @kearos/plugin-hello-backend
342+
npm notice version: 0.2.1
343+
npm notice filename: kearos-plugin-hello-backend-0.2.1.tgz
344+
npm notice package size: 1.8 kB
345+
npm notice unpacked size: 4.1 kB
346+
npm notice shasum: e7f58.............................bbd05e
347+
npm notice integrity: sha512-uhBJRSVioTMTd[...]xJ6Ti9WH+qluA==
348+
npm notice total files: 5
349+
npm notice
350+
npm notice Publishing to https://registry.npmjs.org/ with tag latest and public access
351+
Authenticate your account at:
352+
https://www.npmjs.com/auth/cli/ebdff4ea-a53d-4575-9786-65a8984815de
353+
Press ENTER to open in the browser..
354+
```
355+
356+
Once you do, it should return with the following:
357+
358+
```sh
359+
+ @kearos/plugin-hello-backend@0.2.1
360+
```
361+
362+
We've completed our work on the backend plugin.

0 commit comments

Comments
 (0)