-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
Replace client-side context with getStartServices API #49691
Comments
Pinging @elastic/kibana-platform (Team:Platform) |
After experimenting with the implementation here, I'm leaning towards a slightly different API, similar to what @restrry brought up a couple weeks ago: interface CoreSetup {
getStartServices(): Promise<[CoreStart, TPluginStartDependencies]>;
} Benefits:
Drawbacks:
|
I like the revised suggestion. Even though the type signature helps, it's not obvious that this is really just returning the CoreStart API's. To keep the naming consistent can we rename the method to interface CoreSetup {
getCoreStart(): Promise<[CoreStart, TPluginStartDependencies]>;
} |
I think this name isn't quite right either though, since it returns more than just CoreStart. Maybe a more helpful name would be |
It's quite late in the decision process so I won't interfere, however I'm not a big fan of the revised proposal to be honest, as it makes quite unclear on when this will actually be resolved, and feels less like a surface API than the initial one imho. I think I did prefer the initial proposal. I would probably have gone for something like would be used like core.application.register({
id: 'myApp',
title: 'My App',
async mount(context /* deprecated */, params) {
return setup.whenCoreStart(({core, dependencies}) => { // or `setup.afterStartup` or something
const { renderApp } = await import('./application');
return renderApp(core, dependencies, params);
});
}
}); instead of the current implementation of #50231 which is core.application.register({
id: 'myApp',
title: 'My App',
async mount(context /* deprecated */, params) {
const [coreStart, depsStart] = await core.getStartServices();
const { renderApp } = await import('./application');
return renderApp(coreStart, depsStart, params);
}
}); I know it's closer to the original Because when I see the upsides of the alternative,
I'm not sure to understand the actual issue? bindServices receive a handler, we choose when to execute the handler, and we do after core start, so how calling it before start APIs are available is an issue?
I personally find the wrapper of handler way more elegant that a raw promise accessor.
I don't realise at which point this is simpler, so I won't argue with this. |
Just saw this today. Will write up my thoughts when I get a bit more time this week. |
Right, with your proposal above, this would not be a problem. The problem with the initial proposal had to do with how it returned a sync function that couldn't be called until start dependencies had been resolved or it had to be made async. Given those two options, it didn't seem to me that this factory function pattern was very beneficial since it couldn't be used transparently. I prefer the raw Promise accessor pattern personally since it's a bit simpler to mock out. |
This issue evolved from the discussion in #46483
After seeing this play out in practice in a few different areas, I think we're seeing context on the client-side being used very differently than on the server-side.
Server-side context
On the server-side, we're using context providers to:
This makes the context providers on the server a bit more complex (and useful) than just the raw APIs they're built on top of. It also means they're more specific to their usages. For instance, a context provider for HTTP routes would be different than a context provider for a background task.
Client-side context
On the client-side, things are a bit different:
Ultimately, many of the motivations in the original RFC don't apply to the use-cases we see on the client-side.
Since we're using context providers in such a simple way on the client, it does feel like a lot of unnecessary complexity just to get access to some core APIs.
Alternative: Service binder
This leads me to believe that maybe what we really need on the client is a simple way to bind Core and Plugin APIs to a function:
This
bindServices
method would still solve one of the core problems that context currently solves on the client: getting access to APIs available only during thestart
lifecycle for functions registered duringsetup
.Advantages of this approach:
bindServices
at all.Basically this
bindServices
function would be a very simple dependency injector that would respect the calling plugin's dependencies and does not introduce any magic to get any dependency in the system.Disadvantages:
CoreStart
as proposed by a pending RFC though that RFC is primarily focused on the server-side.The text was updated successfully, but these errors were encountered: