Merge pull request #2532 from spotify/freben/ref
feat(freben): add handling and docs for entity references
This commit is contained in:
@@ -7,7 +7,7 @@ description: Architecture Decision Record (ADR) log on Default Catalog File Name
|
||||
## Background
|
||||
|
||||
While the spec for the catalog file format is well described in
|
||||
[ADR002](./adr002-default-catalog-file-format.md), guidance was note provided as
|
||||
[ADR002](./adr002-default-catalog-file-format.md), guidance was not provided as
|
||||
to the name of the catalog file.
|
||||
|
||||
Following discussion in
|
||||
@@ -23,4 +23,4 @@ catalog-info.yaml
|
||||
```
|
||||
|
||||
This name is a default, **not a requirement**. The catalog file will work with
|
||||
Backstage irregardless of its name.
|
||||
Backstage regardless of its name.
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
---
|
||||
id: adrs-adr009
|
||||
title: ADR009: Entity References
|
||||
description: Architecture Decision Record (ADR) log on Entity References
|
||||
---
|
||||
|
||||
## Background
|
||||
|
||||
While the spec for the catalog file format is well described in
|
||||
[ADR002](./adr002-default-catalog-file-format.md), guidance was not provided as
|
||||
to how one is expected to express references to other entities in the catalog.
|
||||
There was also some confusion on how to reference entities in URLs in the
|
||||
Backstage frontend.
|
||||
|
||||
Following discussion in
|
||||
[Issue 1947](https://github.com/spotify/backstage/issues/1947), a decision was
|
||||
made.
|
||||
|
||||
## Entity References in YAML files
|
||||
|
||||
The textual format, as written by humans, to reference entities by name is on
|
||||
the following form, where square brackets denote optionality:
|
||||
|
||||
```
|
||||
[<kind>:][<namespace>/]<name>
|
||||
```
|
||||
|
||||
That is, it is composed of between one and three parts in this specific order,
|
||||
without any additional encoding, with those exact separator characters.
|
||||
Optionality of `kind` and `namespace` are contextual, and they may or may not
|
||||
have default contextual fallback values.
|
||||
|
||||
When that format is insufficient or when machine made interchange formats wish
|
||||
to express such relations in a more expressive form, a nested structure on the
|
||||
following form can be used:
|
||||
|
||||
```yaml
|
||||
kind: <kind>
|
||||
namespace: <namespace>
|
||||
name: <name>
|
||||
```
|
||||
|
||||
Of these, only `name` is always required. Optionality of `kind` and `namespace`
|
||||
are contextual, and they may or may not have default contextual fallback values.
|
||||
All other possible key values in this structure are reserved for future use.
|
||||
|
||||
A system or user wanting to express a full entity name that is always valid,
|
||||
shall supply the entire triplet whether using the string form or the compound
|
||||
form.
|
||||
|
||||
A full description of the format can be found
|
||||
[in the documentation](https://backstage.io/docs/features/software-catalog/references).
|
||||
|
||||
## Entity References in URLs
|
||||
|
||||
Where entities are referenced by name in the Backstage frontend, the URL
|
||||
containing the reference shall take the following form:
|
||||
|
||||
```
|
||||
:namespace/:kind/:name
|
||||
```
|
||||
|
||||
All three parts are required under all circumstances. The default value for the
|
||||
`namespace` in the catalog is the string `"default"`, if the entity does not
|
||||
specify one explicitly in `metadata.namespace`.
|
||||
|
||||
This means that we do not encourage the string form of entity references to be
|
||||
used as a single URL segment, due to the use of URL-unsafe characters leading to
|
||||
possible risk, confusion, and uglier URLs.
|
||||
@@ -0,0 +1,104 @@
|
||||
---
|
||||
id: references
|
||||
title: Entity References
|
||||
description: How to express references between entities
|
||||
---
|
||||
|
||||
Entities commonly have a need to reference other entities. For example, a
|
||||
[Component](descriptor-format.md#kind-component) entity may want to declare who
|
||||
its owner is by mentioning a Group or User entity, and a User entity may want to
|
||||
declare what Group entities it is a member of. This article describes how to
|
||||
write those references in your yaml entity declaration files.
|
||||
|
||||
Each entity in the catalog is uniquely identified by the triplet of its
|
||||
[kind](descriptor-format.md#apiversion-and-kind-required),
|
||||
[namespace](descriptor-format.md#namespace-optional), and
|
||||
[name](descriptor-format.md#name-required). But that's a lot to type out
|
||||
manually, and in a lot of circumstances, both the kind and the namespace are
|
||||
fixed, or possible to deduce, or could have sane default values. So in order to
|
||||
help the writer, the catalog has a few tricks up its sleeve.
|
||||
|
||||
Each reference can be expressed in one of two ways: as a compact string, or as a
|
||||
compound reference structure.
|
||||
|
||||
## String References
|
||||
|
||||
This is the most common alternative, that should be used in almost all
|
||||
circumstances.
|
||||
|
||||
The string is on the form `[<kind>:][<namespace>/]<name>`, that is, it is
|
||||
composed of between one and three parts in this specific order, without any
|
||||
additional encoding:
|
||||
|
||||
- Optionally, the kind, followed by a colon
|
||||
- Optionally, the namespace, followed by a forward slash
|
||||
- The name
|
||||
|
||||
The name is always required. Depending on the context, you may be able to leave
|
||||
out the kind and/or namespace. If you do, it is contextual what values will be
|
||||
used, and the relevant documentation should specify which rule applies where.
|
||||
All strings are case insensitive.
|
||||
|
||||
```yaml
|
||||
# Example:
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: petstore
|
||||
namespace: external-systems
|
||||
description: Petstore
|
||||
spec:
|
||||
type: service
|
||||
lifecycle: experimental
|
||||
owner: group:pet-managers
|
||||
implementsApis:
|
||||
- petstore
|
||||
- internal/streetlights
|
||||
- hello-world
|
||||
```
|
||||
|
||||
The field `spec.owner` is a reference. In this case, the string
|
||||
`group:pet-managers` was given by the user. That means that the kind is `Group`,
|
||||
the namespace is left out, and the name is `pet-managers`. In this context, the
|
||||
namespace was chosen to fall back to the value `default` by the code that parsed
|
||||
the reference, so the end result is that we expect to find another entity in the
|
||||
catalog that is of kind `Group`, namespace `default` (which, actually, also can
|
||||
be left out in its own yaml file because that's the default value there too),
|
||||
and name `pet-managers`.
|
||||
|
||||
The entries in `implementsApis` are also references. In this case, none of them
|
||||
need to specify a kind since we know from the context that that's the only kind
|
||||
that's supported here. The second entry specifies a namespace but the other ones
|
||||
don't, and in this context, the default is to refer to the same namespace as the
|
||||
originating entity (`external-systems` here). So the three references
|
||||
essentially expand to `api:external-systems/petstore`,
|
||||
`api:internal/streetlights`, and `api:external-systems/hello-world`. We expect
|
||||
there to exist three API kind entities in the catalog matching those references.
|
||||
|
||||
## Compound References
|
||||
|
||||
This is a more verbose version of a reference, where each part of the
|
||||
kind-namespace-name triplet is expressed as a field in a structure. This format
|
||||
can be used where necessary, such as if either of the three elements contain
|
||||
colons or forward slashes. Avoid using it where possible, since it is harder to
|
||||
read and write for humans.
|
||||
|
||||
```yaml
|
||||
# Example:
|
||||
apiVersion: backstage.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: petstore
|
||||
description: Petstore
|
||||
spec:
|
||||
type: service
|
||||
lifecycle: experimental
|
||||
owner:
|
||||
kind: Group
|
||||
name: aegis-imports/pet-managers
|
||||
```
|
||||
|
||||
In this example, the `spec.owner` has been broken apart since the name was
|
||||
complex. The kind happened to be written with an uppercase letter G, which also
|
||||
works. The namespace was left out just like in the string version above, which
|
||||
is handled identically.
|
||||
Reference in New Issue
Block a user