-
Notifications
You must be signed in to change notification settings - Fork 45
DI API Tweak #72
Comments
Should // new hotness
const MiddlewareOnlyPlugin = (ctx, next) => next();
// new new hotness
const MiddlewareOnlyPlugin = () => (ctx, next) => next(); |
I would rather have less unnecessary wrapping things |
Doesn't |
We can have it return an object, similar to how it works today in |
While I am a fan of a single #backToPluginFullCircle |
It seems like two methods will still cause some confusion. We should be able to infer the type of thing you are registering, correct? Just wondering if something like the following is possible:
|
@KevinGrandon we could remove // can't do this anymore
const MiddlewareOnlyPlugin = (ctx, next) => next();
app.plugin(MiddlewareOnlyPlugin);
// would need to be
const MiddlewareOnlyPlugin = withMiddleware((ctx, next) => next()); // or some equivalent wrapper
app.plugin(MiddlewareOnlyPlugin); |
In terms of mitigating confusion, I like the idea of a generalized |
That is what we need to figure out tho. The big open questions for me are:
|
Potentially we can solve all these problems if we come up with a better name for a. attach a middleware to a plugin With our current api, we accomplish (b) using a special case of (a) by "attaching" a middleware to an empty plugin. In other words: // (a)
withMiddleware(plugin, (ctx, next) => next());
// (b)
withMiddleware((ctx, next) => next()); My biggest gripe with this is it just feels unnatural. We could rename (b) to something else like |
After some discussion, I think the consensus is some variation of: // all object keys are optional
createPlugin({
requires: {dep: DepToken},
provides({dep}) {
return something
},
middleware(deps, something) {
return (ctx, next) => {}
}
}) or createPlugin({dep: DepToken}, ({dep}) => ({
provides: something,
middleware: (ctx, next) => {}
})) Other variations include using the word Another suggestion is to have an overload for Registration would look like: const MyPlugin: Plugin = createPlugin(...); // same API for service plugin, middleware plugin and service+middleware plugin
app.register(SomeToken, MyPlugin);
app.register(SomeConfigToken, 1000); |
I'm pretty sold on option 1, and I'm partial to using |
Actually now I'm partial to |
Final API is: createPlugin({
deps: {dep: DepToken},
provides: ({dep}) => {
return something
},
middleware: (deps, something) => {
return (ctx, next) => {}
}
})
app.register([Token, ] PluginOrValue);
app.middleware(middleware); |
On a side note, we are also using a convention of returning a object with interface For example createPlugin({
deps: {I18n: I18nToken},
middleware({I18n}) {
return (ctx, next) => {
const i18n = I18n.from(ctx); // get an instance that is scope by request
i18n.translate('foo');
}
},
}) |
I have found myself confusing when to use
app.register
vsapp.configure
a few times when working through the DI migration. To give some context, we have two things that can be given to the DI system:plugins
andvalues
. Avalue
is given to the DI system viaapp.configure
and aplugin
is given to the DI system viaapp.register
. There are a few reasons for this distinction, but suffice to say that it matters.The problem for me is that
app.register
intuitively feels like it should work with things that are not plugins. For example:When choosing between the two options above, they both seem equally likely to be correct, when in fact
app.configure
is correct, andapp.register
is incorrect.To fix this, I want to propose a small tweak to the api by renaming
app.register
toapp.plugin
.This makes it much more clear that only
plugins
can be registered with the DI system viaapp.plugin
and configuration viaapp.configure
. It also allows us to say "registered with theDI system" without conflating it with app.register, sinceapp.configure
is also "registering" something with the DI system.Along side this change, I think it would make sense to make the following tweaks.
withDependencies
tocreatePlugin
createPlugin
(previouslywithDependencies
)withMiddleware
for pure functional pluginsLets take a look at some examples of the old vs new apis.
Overall I think this improves the readability and clarity of fusionjs code and reduces some boilerplate.
The only thing that could still use some work is pure functional middleware with dependencies.
This is still a little funky, because nothing is going
with
the middleware. One option is we could support just returning afunction
directly, but that would impose the restriction that programmatic apis of plugins couldn't be functions. I'm open to ideas on how to make this better, but I don't think it is a dealbreaker for shipping.Comments?
The text was updated successfully, but these errors were encountered: