Merge pull request #21812 from backstage/docs/di-context
Docs: Add context to DI documentation
This commit is contained in:
@@ -18,6 +18,10 @@ Each extensions has a number of different properties that define how it behaves
|
||||
|
||||
### ID
|
||||
|
||||
<!--
|
||||
Update this to be 3 different sections: name, kind and namespace
|
||||
-->
|
||||
|
||||
The ID of an extension is used to uniquely identity it, and it should ideally by unique across the entire Backstage ecosystem. For each frontend app instance there can only be a single extension for any given ID. Installing multiple extensions with the same ID will either result in an error or one of the extensions will override the others. The ID is also used to reference the extensions from other extensions, in configuration, and in other places such as developer tools and analytics.
|
||||
|
||||
### Output
|
||||
@@ -85,20 +89,64 @@ TODO
|
||||
|
||||
## Extension Inputs
|
||||
|
||||
TODO
|
||||
<!--
|
||||
|
||||
## Configuration
|
||||
Introduce the concept of extension inputs and how they use extension data to reference types just like outputs
|
||||
|
||||
TODO
|
||||
Show how to use the `createExtensionInput` API to create an input for an extension.
|
||||
|
||||
## Configuration Schema
|
||||
- Example of creating a single input
|
||||
|
||||
TODO
|
||||
Talk about different types of inputs, singleton vs array + optional vs required.
|
||||
|
||||
- Example of creating an optional singleton input - not the value is no longer an array
|
||||
|
||||
Talk about the shape of the input values and that you have access to the AppNode node in addition to the data, but discourage use of AppNode.
|
||||
|
||||
- Example of how to access the AppNode next to the input data
|
||||
|
||||
-->
|
||||
|
||||
## Extension Configuration
|
||||
|
||||
<!--
|
||||
|
||||
Introduce the concept of extension configuration, highlight that it's different from app config
|
||||
|
||||
Show how to define a configuration schema for an extension, talk about it using zod (link to zod), in general explain everything there is to know about the schema
|
||||
|
||||
- Example that creates a configuration schema for an extension
|
||||
|
||||
Show how to provide configuration for an extension - keep this part short, and instead link to the architecture section that talks about writing configuration
|
||||
|
||||
- One example of a YAML configurations for the above extension
|
||||
|
||||
-->
|
||||
|
||||
## Extension Creators
|
||||
|
||||
TODO
|
||||
<!--
|
||||
|
||||
Introduce the concept of extension creators, talk about how they are used to provide an opinionated way of creating extensions for specific use cases. Mention a few of the built-in creators, link to the reference section on built-in extension kinds (TBD).
|
||||
|
||||
- Example of using an existing extension creator to create an extension
|
||||
|
||||
Explain that each extension creator creates a specific "kind" of extensions - introduce the concept of extension kinds. Show an example of how the kind is used to build up the ID.
|
||||
|
||||
- Example of creating a new extension creator for creating a specific kind of extension
|
||||
|
||||
Explain that extension creators should be exported from library packages (`-react`) rather than plugin packages.
|
||||
|
||||
-->
|
||||
|
||||
## Extension Boundary
|
||||
|
||||
TODO
|
||||
<!--
|
||||
|
||||
Introduce the need for extension specific React contexts, for example error boundaries and analytics.
|
||||
|
||||
Any React elements that are rendered by extension creators should be wrapped in the `ExtensionBoundary`
|
||||
|
||||
- Example of how to use the `ExtensionBoundary` in an extension creator
|
||||
|
||||
-->
|
||||
|
||||
@@ -7,3 +7,87 @@ description: Frontend plugins
|
||||
---
|
||||
|
||||
> **NOTE: The new frontend system is in a highly experimental phase**
|
||||
|
||||
## Introduction
|
||||
|
||||
<!--
|
||||
|
||||
Introduce frontend plugins and how each of them is shipped as a separate package. Highlight that each package should only export a single plugin instance.
|
||||
|
||||
-->
|
||||
|
||||
## Creating a Plugin
|
||||
|
||||
<!--
|
||||
|
||||
How to create a simple plugin
|
||||
|
||||
-->
|
||||
|
||||
```ts
|
||||
export const myPlugin = createPlugin({
|
||||
id: 'my-plugin',
|
||||
});
|
||||
```
|
||||
|
||||
<!--
|
||||
|
||||
Note that this plugin is useless in itself, and you need to provide extra options to make it useful, in particular extensions.
|
||||
|
||||
-->
|
||||
|
||||
### Plugin ID
|
||||
|
||||
<!--
|
||||
|
||||
link to relevant docs
|
||||
|
||||
-->
|
||||
|
||||
### Plugin Extensions
|
||||
|
||||
<!--
|
||||
|
||||
- Example of how this option is used in `createPlugin`
|
||||
|
||||
link to relevant docs
|
||||
|
||||
-->
|
||||
|
||||
### Plugin Routes
|
||||
|
||||
<!--
|
||||
|
||||
- Example of how this option is used in `createPlugin`
|
||||
|
||||
link to relevant docs
|
||||
|
||||
-->
|
||||
|
||||
### Plugin External Routes
|
||||
|
||||
<!--
|
||||
|
||||
- Example of how this option is used in `createPlugin`
|
||||
|
||||
link to relevant docs
|
||||
|
||||
-->
|
||||
|
||||
### Plugin Feature Flags
|
||||
|
||||
<!--
|
||||
|
||||
- Example of how this option is used in `createPlugin`
|
||||
|
||||
link to relevant docs
|
||||
|
||||
-->
|
||||
|
||||
## Installing a Plugin in an App
|
||||
|
||||
<!--
|
||||
|
||||
Quick intro, but link back to app docs for more details
|
||||
|
||||
-->
|
||||
|
||||
@@ -7,3 +7,41 @@ description: Frontend extension overrides
|
||||
---
|
||||
|
||||
> **NOTE: The new frontend system is in a highly experimental phase**
|
||||
|
||||
## Introduction
|
||||
|
||||
<!--
|
||||
|
||||
Introduce extension overrides and how they can be shipped in separate packages but also internally within a project too.
|
||||
|
||||
Talk about how extension overrides
|
||||
|
||||
-->
|
||||
|
||||
## Creating a Extension Override
|
||||
|
||||
<!--
|
||||
|
||||
How to create an extension override and export it from a package.A
|
||||
|
||||
- Example using the default exports
|
||||
|
||||
You can also create them directly withing the app for local overrides.
|
||||
|
||||
- Example of installing an override directly into an app
|
||||
|
||||
Mention that in can still be a good idea to split your overrides out into separate packages in large projects. But it's up to you to decide how to group the extensions into extension overrides.
|
||||
|
||||
-->
|
||||
|
||||
## Overriding Existing Extensions
|
||||
|
||||
<!--
|
||||
|
||||
To override an existing extension you need to provide an extension through an extension override that has the same ID as the existing extension. That is, all of kind, namespace and name must match the extension you want to override.
|
||||
|
||||
This means that you typically need to provide an explicit namespace when overriding extensions from a plugin.
|
||||
|
||||
- Example of how to create an extension override for an existing extension from some plugin
|
||||
|
||||
-->
|
||||
|
||||
@@ -9,3 +9,142 @@ description: Frontend routes
|
||||
> **NOTE: The new frontend system is in a highly experimental phase**
|
||||
|
||||
See [routing system docs](../../plugins/composability.md#routing-system)
|
||||
|
||||
## Introduction
|
||||
|
||||
<!--
|
||||
|
||||
Routing system of backstage - what's the prupose
|
||||
|
||||
Explain the indirection needed to route between plugins. For example what do we do if plugin A want to link to plugin B, but plugin B is not installed? How can we support this in an app?
|
||||
|
||||
How can we let an integrator decice whether plugin A should link to plugin B or plugin C? (with some good real-work examples, e.g. catalog -> scaffolder create page / catalog-import plugin)
|
||||
|
||||
-->
|
||||
|
||||
## Route References
|
||||
|
||||
<!--
|
||||
|
||||
Explain what a route reference is - then explain how it solves the problem outlined above.
|
||||
|
||||
Explain that we use route references to represent a path in an app. Each referenced path is unique for each app, but in different apps the same route ref might point to different paths.
|
||||
|
||||
-->
|
||||
|
||||
### Creating a Route Reference
|
||||
|
||||
<!--
|
||||
|
||||
Example using `createRouteRef` + passing it to a page extension
|
||||
|
||||
-->
|
||||
|
||||
### Using a Route Reference
|
||||
|
||||
<!--
|
||||
|
||||
Example using `useRouteRef` in a component
|
||||
|
||||
-->
|
||||
|
||||
### Route Path Parameters
|
||||
|
||||
<!--
|
||||
Example using path parameters, both createRouteRef and useRouteRef
|
||||
-->
|
||||
|
||||
### Providing Route References to Plugins
|
||||
|
||||
<!--
|
||||
Show how to provide routes through createPlugin({ routes: })
|
||||
-->
|
||||
|
||||
## External Router References
|
||||
|
||||
<!--
|
||||
Explain the need for external route refs
|
||||
|
||||
Explain all of create, use and provide
|
||||
|
||||
-->
|
||||
|
||||
### Binding External Route References
|
||||
|
||||
<!--
|
||||
Example using `createApp`
|
||||
|
||||
Example using config
|
||||
|
||||
-->
|
||||
|
||||
### Optional External Route References
|
||||
|
||||
<!--
|
||||
Talk about how external routes must be bound or app will crash, but you can make them optional too
|
||||
|
||||
useRouteRef can return undefined for optional external routes
|
||||
-->
|
||||
|
||||
## Sub Route References
|
||||
|
||||
<!--
|
||||
|
||||
Explain the need for external route refs - both as a tool for routing within a plugin, but also allow external routes to point to sub routes
|
||||
|
||||
Talk about how sub routes declare an explicit path - can't be decided by the app/integrator. They are hard-coded in the plugin in parallel to the internal routing structure of the plugin itself.
|
||||
|
||||
Explain all of create, use and provide
|
||||
-->
|
||||
|
||||
```ts
|
||||
/*
|
||||
|
||||
Some examples
|
||||
|
||||
export const indexPageRouteRef = createRouteRef()
|
||||
|
||||
export const catalogPlugin = createPlugin({
|
||||
id: 'catalog,
|
||||
routes: {
|
||||
index: indexPageRouteRef,
|
||||
},
|
||||
})
|
||||
|
||||
// in catalog plugin
|
||||
|
||||
import {indexPageRouteRef} from '../../routes
|
||||
|
||||
const link = useRouteRef(indexPageRouteRef)
|
||||
|
||||
// scaffolder
|
||||
|
||||
export const catalogIndexPageRouteRef = createExternalRouteRef({
|
||||
defaultTarget: 'catalog/index',
|
||||
})
|
||||
|
||||
export const scaffolderPlugin = createPlugin({
|
||||
id: 'scaffolder,
|
||||
externalRoutes: {
|
||||
catalogIndex: catalogIndexPageRouteRef,
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
import {catalogIndexPageRouteRef} from '../../routes
|
||||
|
||||
const link = useRouteRef(catalogIndexPageRouteRef)
|
||||
|
||||
// app
|
||||
|
||||
import {catalogPlugin} from '@backstage/plugin-catalog'
|
||||
|
||||
const app = createApp({
|
||||
bindRoutes({bind}) {
|
||||
bind(scaffolderPlugin, {
|
||||
catalogIndex: catalogPlugin.routes.index,
|
||||
})
|
||||
},
|
||||
})
|
||||
*/
|
||||
```
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
id: references
|
||||
title: Value References
|
||||
sidebar_label: Value References
|
||||
# prettier-ignore
|
||||
description: Value References
|
||||
---
|
||||
|
||||
> **NOTE: The new frontend system is in a highly experimental phase**
|
||||
|
||||
<!--
|
||||
|
||||
Describe the generic concept of references as used for ApiRef, ExtensionDataRef, RouteRef, ComponentRef, etc.
|
||||
|
||||
Talk about the usage and how helper functions allows type-safe access to the values that the references represent.
|
||||
|
||||
-->
|
||||
Reference in New Issue
Block a user