Versioned API support
See original GitHub issueI’d like this to be more of a conversation starter about this topic, is it a needed feature? Does anybody else have this issue? The proposed solutions are just really quick ideas around the topic.
Feature Suggestion
Usually, APIs are evolving during their lifetimes with different versions. In the current form, every version of an API spec will (and should) have its own API entity in backstage. However, all of these versions of APIs are actually tied to a component. From the POV of a service, it provides 1 API with different versions, but it is rendered right now as the service provides all the versions (which is technically true) but the user experience in finding the correct version can be bad if you have a lot of versions for your API.
I suggest that API specs could have a similar model like groups and users. Where I could see 1 “parent” API and I would be able to choose which version of that API I’d like to see. example: with entities:
Possible Implementation
I think there could be a couple of ways to do this.
One idea is to introduce a new entity kind, stg like GroupApi. These could have a spec.apis
array, where you should list your regular API entities. With this approach, it might be more clear to create frontend components for the GroupApis.
Another idea is to extend the current API entity with a spec.versions
array, where you could list the other versions of this API spec. In this case, handling on the frontend might not be as clean, there would be not a clear distinction between regular API specs and GroupApi specs.
As a POC I was able to kinda hack around and create something like I mentioned above. For this, I used the API entity’s existing spec.owner
field. Where 1 API is actually owning other APIs and the top-level parent API is owned by a team/user. If you set up your APIs like this, then there is a possibility to create a frontend component that takes advantage of the useRelatedEntities
hook to list all the entities that the current API owns.
It is a hack since the official documentation states that the spec.owner
field should be only user or groups. In this case, I used an api
as an owner.
In the current form API entities’ spec.definition
is a required field, however, the parent API will not have a direct definition so you’d need to use some dummy texts.
An unsolved problem with this is handling the frontend for it, we could update the ApiDefinitionCard
to handle the versioning, but it should handle the cases where the API is just a regular API and where it is a parent API.
Issue Analytics
- State:
- Created a year ago
- Reactions:11
- Comments:13 (8 by maintainers)
Top GitHub Comments
After spending some time familiarizing myself with the Backstage model, and mapping some of our architecture to these concepts, I found versioning in general was a bit of a gap.
I agree with all of your points making the case for API versions, but I would also argue that most of them apply equally to Components, which also evolve over their lifetime, with potential changes to relations and dependencies along the way. The UX of a library or framework documentation page with a version drop-down immediately comes to mind.
One pretty important piece that I’d like to discuss is whether we think it’s alright to have the API definitions not be easily available to the rest of the Backstage system, essentially having them be confined to the API docs plugin and related frontend integrations.
Imagine the following frontend API:
It’d add a flexible layer in the frontend that we could hook up to the existing inline definitions, a possible API storage in an
api-docs-backend
, or external services.The big downside is that we now no longer have easy access to the API definitions from other backend plugins or external services. API entities essentially become opaque. That’s unless we also add a similar interface to implement in the backend, which becomes a lot more complex if you want to bridge to services outside the Backstage ecosystem.
Is that fine? Are API definitions in the end mostly intended for consumption by users anyway? I do feel that it would not for example be wise to rely on machine reading of the definitions in the catalog to directly drive infrastructure. Such as loading gRPC definitions straight from catalog API entities into an Envoy transcoder. It’s coupling that I think is better to set up in a way the keeps the catalog away from critical infrastructure configuration.