-
Notifications
You must be signed in to change notification settings - Fork 6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Switch to automatic dependency injection of Utility APIs #2285
Conversation
createApiFactory({ | ||
api: catalogApiRef, | ||
deps: { discoveryApi: discoveryApiRef }, | ||
factory: ({ discoveryApi }) => new CatalogClient({ discoveryApi }), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's an example of what it looks like from a plugin's point of view
Not intending for this to build yet, will update docs and create-app etc once we've settled any discussions 😁 Please do review still :> |
19e7169
to
be5a9f3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
Will this require changes in plugins? |
@dtuite preferably, but not immediately. Plugins can still choose to not supply default factories for their APIs, but then they have to be wired up in the app like before. For the Travis and GH PRs plugins to be updated we'll need a new release with these changes, so that they can start exposing the factories, and then remove them from the app. |
@Rugvip we will work on that once this is merged. We're also working on migrating to the new routing API and tabs on the catalog entity page. |
Adding docs in a followup PR so we can have a more focused review |
By the way, it would be great to get a release cut soon so people can more easily migrate plugins which are not in the monorepo over to the new APIs. 🤞 |
Fixes #2182
Will add doc changes to this PR once we're happy with the changes.
Previous design was a single API registry where all APIs where wired up in
apis.ts
, simple but tedious and a lot of code required in the App.This switches out to a more complex setup, but where the work of wiring up plugins in moved out from the app, making it significantly easier to add plugins to an existing app.
apis.ts
still exists, but it's only used for overriding the default api factories shipped in@backstage/core
and each plugin.Instead of directly instantiating all APIs and startup, we now lazy-load them as they are asked for. There's a quick sanity check at startup to make sure that there are no cycles in the dependency tree, but other than that failures will be encountered later. The instantiation is still synchronous, which is very much intentional, as I don't think we want plugins to do any kind of work at startup.
Couple of naming things to discuss:
api
in the external API. Since there's no other way to instantiate an API than using a factory, I felt thatapiFactories
anddefaultApiFactories
etc. were a bit redundant and went with the shorter form.implements
field, which I renamed toapi
. I thinkapi
captures the intention a bit better and is a bit more readable. I'm trying to skip having to think about "creating API factories", and make the mental model be that we're creating APIs. Another option here would beapiRef
, since that's the actual value, but I feel thatapi
is nicer, and typescript should take care of avoiding any confusion there anyway. It also aligns withuseApi
, where you're also actually passing in anApiRef
.createApiFactory
. Here I did feel likecreateApi
would be a bit too misleading, and I left in theFactory
word just to give a hint at what it is we're actually doing.