chore: more text

Signed-off-by: Johan Haals <johan.haals@gmail.com>
This commit is contained in:
Johan Haals
2022-10-04 16:18:27 +02:00
parent 8037c55ea9
commit 6a8f7e5a73
+106 -16
View File
@@ -8,22 +8,32 @@ description: About Backend
**DISCLAMER: The new backend system is under active development and is not considered stable**
This is an example of how you create, start and add existing plugins to your backend.
```ts
import { createBackend } from '@backstage/backend-defaults';
const backend = createBackend();
// backend.add(catalogPlugin());
await backend.start();
```
### Overview
The default backend provides several services out of the box which are available to all plugins but there might cases where you want to provide a completely new service in your installation.
The default backend provides several _services_ out of the box which includes access to config, logging, scheduling and more.
Service are declared using their _serviceRef_ in the `deps` section of plugin or module requiring them and are then available in the `init` method of the plugin or module.
### Service Refs
A serviceRef is a named reference to an interface which are later used to resolve the actual service implementation. Conceptually this is very similar to `ApiRef`s in the frontend.
A serviceRef is a named reference to an interface which are later used to resolve the concrete service implementation. Conceptually this is very similar to `ApiRef`s in the frontend.
Services is what provides common utilities that previously resided in the `PluginEnvironment` such as Config, Logging and Database.
On startup the backend will make sure that the services are initialized before being passed to the plugin/module that depend on them.
ServiceRefs does contain a scope which is used to determine if the serviceFactory creating the service will create a new instance for each plugin/module or if it will be shared. `plugin` scoped services will be created once per plugin and `root` scoped services will be created once per backend instance.
ServiceRefs contain a scope which is used to determine if the serviceFactory creating the service will create a new instance scoped per plugin/module or if it will be shared. `plugin` scoped services will be created once per plugin/module and `root` scoped services will be created once per backend instance.
#### Defining a ServiceRef
In its simplest form the serviceRef can be defined like this referencing the type of the actual implementation.
```ts
import {
createServiceFactory,
@@ -65,7 +75,7 @@ export const exampleServiceRef = createServiceRef<ExampleApi>({
### Overriding services
In this example replace the default log implementation with a custom one.
In this example replace the default log implementation with a custom logger.
```ts
import {
@@ -92,15 +102,39 @@ const backend = createBackend({
})
```
#### API Overview
`createBackend`
`createBackendPlugin`
`createBackendModule`
`createServiceRef`
`createExtensionPoint`
### Writing Plugins
## Writing Plugins
### Writing modules
```ts
import { configServiceRef, createBackendPlugin } from '@backstage/backend-plugin-api';
// export type ExamplePluginOptions = { exampleOption: boolean };
export const examplePlugin = createBackendPlugin({
// unique id for the plugin
id: 'example',
// It's possible to provide options to the plugin
// register(env, options: ExamplePluginOptions) {
register(env) {
env.registerInit({
deps: {
logger: loggerServiceRef,
},
// logger is provided by the backend based on the dependency on loggerServiceRef above.
async init({ logger }) {
logger.info('Hello from example plugin');
},
});
},
});
```
The plugin can then be installed to the backend using
```ts
backend.add(examplePlugin());
// Options can be passed to the plugin
// backend.add(examplePlugin({ exampleOption: true}));
```
## Writing Modules
Some facts about modules
@@ -110,13 +144,35 @@ Some facts about modules
A module depend on the extensionPoint exported by the plugins library package(eg `catalog-node`, `scaffolder-backend`) and does not directly declare a dependency on the plugin package itself.
Here's an example on how to create a module that adds a new processor using the `catalogProcessingExtensionPoint`
```ts
import { createBackendModule } from '@backstage/backend-plugin-api';
import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node';
import { MyCustomProcessor } from './processor';
### Overwriting services
export const exampleCustomProcessorCatalogModule = createBackendModule({
moduleId: 'exampleCustomProcessor',
pluginId: 'catalog',
register(env) {
env.registerInit({
deps: {
catalog: catalogProcessingExtensionPoint,
},
async init({ catalog }) {
catalog.addProcessor(new MyCustomProcessor());
},
});
},
});
```
### Extension Points
Modules depend on extension points just as a regular dependency but specifying it in the `deps` section.
#### Defining an Extension Point
```ts
import { createExtensionPoint } from '@backstage/backend-plugin-api';
@@ -130,4 +186,38 @@ export const ScaffolderActionsExtensionPoint =
});
```
#### Registering an Extension Point
Extension points are registered by a plugin and extended by modules.
### Testing
Utilities for testing backend plugins and modules are available in `@backstage/backend-test-utils`.
```ts
import { startTestBackend } from '@backstage/backend-test-utils';
describe('Example', () => {
it('should do something', async () => {
await startTestBackend({
// mock services can be provided to the backend
services: [someServiceFactory],
// plugins and modules for testing
features: [testModule()],
});
// assertions
});
});
```
## Package structure
The package relationship between plugins, modules and extension are illustrated in the following diagram.
Taken with an artificial foobar backend plugin.
- `plugin-foobar-backend` houses the plugin and registers the extension points into the backend system.
- `plugin-foobar-common` houses the shared types including the Extension Point registered by the backend.
- `plugin-foobar-XYZ-module` houses the modules that extend the foobar backend with extension points imported from `plugin-foobar-common`