-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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
Add support for class based plugins #1673
Add support for class based plugins #1673
Conversation
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.
This looks amazing, good work! I've added a few notes.
lib/pluginDecorators.js
Outdated
'use strict' | ||
|
||
const { kPluginMetadata } = require('./symbols') | ||
require('reflect-metadata') |
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.
I'm -1 on adding any dependency that modifies global state. Can we do this without this library or with a work-around?
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.
We could store it at the plugin using a symbol.
"target": "es6", | ||
"module": "commonjs", | ||
"strict": false, | ||
"experimentalDecorators": true |
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.
I think I've heard they are going to change this in the next version of TS. When will decorators be out of experimental? Have you got any info?
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.
No, I got no information on this.
However I think we will know in two days: microsoft/TypeScript#30555
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.
Decorators are still experimental in typescript 3.5.x.
import { DecorateInstance } from 'fastify' | ||
|
||
class MyPlugin { | ||
@DecorateInstance() |
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.
We would need to add a decorator on the class itself to enable/disable encapsulation, i.e. setting https://github.com/fastify/fastify-plugin/blob/966248ce75eebe58727aaa5c676d410b4641d236/index.js#L16
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.
I agree. Shall we add this decorator in fastify-plugin
? It could provide the other features of fastify-plugin
as a decorator, too.
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.
I opened a PR (fastify/fastify-plugin#73) in the fastify-plugin repository that adds such a decorator.
Are we planning on landing this in v2? |
I would prefer typescript decorators to exit experimental status first.
Likely v3.
Il giorno mar 28 mag 2019 alle 19:31 Ethan Arrowood <
notifications@github.com> ha scritto:
… Are we planning on landing this in v2?
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#1673?email_source=notifications&email_token=AAAMXY7JO2C3BI3Z663YCIDPXVT55A5CNFSM4HPRMXU2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODWM3RBA#issuecomment-496613508>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAAMXY7MZHGIM4GI6DTTOELPXVT55ANCNFSM4HPRMXUQ>
.
|
Per @mcollina confirmation, please rebase onto |
Ok, I'll rebase the branch and change the PR. |
5546fc7
to
3c13d7b
Compare
lib/abstractPlugin.js
Outdated
|
||
[kSetInstance] (instance) { | ||
this.instance = instance | ||
} |
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.
I don’t think this class is needed at all. We can just set the instance manually on the object, without using an accessor.
@Get('/') | ||
async handler (request, response) { | ||
t.ok(this.instance) | ||
t.ok(this['instance']) |
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.
why this change?
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.
That wasn't planed to stay. I fixed it.
module.exports.Hook = Hook | ||
module.exports.DecorateRequest = DecorateRequest | ||
module.exports.DecorateReply = DecorateReply | ||
module.exports.DecorateInstance = DecorateInstance |
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.
Would it be possible to use these with JavaScript as well?
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.
The decorators can be used with babel.
Using them without typescript or babel should be possible, but it is not very practical.
I really like this proposal. I'm a bit scared about how this would affect our LTS support, considering that TS decorators are still experimental. Should we land them as experimental here, maybe logging a warning? |
I agree that they should be experimental and a warnung is a good idea. |
If this is to land in Additionally, when #1569 lands I believe some updates will need to be made with this proposal. |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
Just a note: I am waiting until #1569 is being merged before I add typings for the new Decorators that this PR adds. |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
14b637d
to
9527327
Compare
I rebased the branch since #1569 has been merged and added typings for the decorators. |
The test failures seem to be related to |
Hi @SerayaEryn! Really excellent addition. class MyPlugin {
constructor (options) {
// ...
}
@Get('/')
async route (request, reply) {
return 'hello world'
}
}
|
The decorators for the http methods have a second parameter that allows to add additional route options: class MyPlugin {
constructor (options) {
// ...
}
@Get('/', { preHandler: yourPreHandler })
async route (request, reply) {
return 'hello world'
}
} |
This work is impressive. CI is failing, would you mind taking a look? |
The new I take a closer look next week. |
Great PR but I don't like that code is shipped to the core and only typescript is supported. |
Can we provide them as a plugin? |
I think that should be possible. |
If we can pack them as a plugin, it would be fantastic.
Il giorno mer 18 set 2019 alle ore 20:45 Denis Fäcke <
notifications@github.com> ha scritto:
… Can we provide them as a plugin?
I think that should be possible.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1673?email_source=notifications&email_token=AAAMXY5B5UEYR5KR7TPO3C3QKJZNLA5CNFSM4HPRMXU2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD7BB7CI#issuecomment-532815753>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAAMXY2C6WFY7XUQA3EEUOTQKJZNLANCNFSM4HPRMXUQ>
.
|
I'll close this PR and will start working on a module as soon as i can. |
This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
I started looking into a possible implementation of class based plugins (#1655).
There are decorators for each http method:
@Get
,@Post
,@Put
,@Delete
,@Put
,@Head
,@Patch
and@Options
. In addition to that there is a@All
decorator that adds the handler for all http methods. They accept the parameters like the methods on the fastify instance:@Method(path, [options])
Furthermore there is a
@Hook(hook)
decorator that allows to add hooks.These decorators for the http methods and the hook decorator seem to work well.
I also have build decorators, that allow to decorate the fastify instance, request and reply.
However I don't know whether this solution is nice.
It is not possible to check whether the fastify instance, request or reply is already decorated.
And since a function can't access the
this
from the plugin and the request (or reply) the decorated method needs to return another function.Maybe the following approach might be better:
The documentation for the class based plugins is not finished yet.
I think this feature should be marked as experimental as long as the typescript feature is experimental and the proposal is not finalized. And maybe there should be an option that needs to be enabled?
I also noticed that it might be nice to add some kind of
@Plugin(metadata)
decorator tofastify-plugin
, that allows to add metadata for a plugin.Checklist
npm run test
andnpm run benchmark