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
Expose router config via getters on Request #2506
Conversation
@@ -320,7 +320,7 @@ function buildRouting (options) { | |||
|
|||
var queryPrefix = req.url.indexOf('?') | |||
var query = querystringParser(queryPrefix > -1 ? req.url.slice(queryPrefix + 1) : '') | |||
var request = new context.Request(id, params, req, query, childLogger) | |||
var request = new context.Request(id, params, req, query, childLogger, context) |
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.
@Eomm Is it the only place where we instantiate Request in runtime, or I missed some?
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.
In the 404 handler we create a new one:
Line 147 in e70fd41
function fourOhFourFallBack (req, res) { |
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.
Added
@@ -30,6 +30,8 @@ export interface FastifyRequest< | |||
hostname: string; | |||
url: string; | |||
method: string; | |||
routerUrl: string; | |||
routerMethod: string; |
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.
@Eomm You suggested exposing router method; are there any cases when you expect router method to differ from request method?
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 can't remember it, could you link me the issue?
The only use case is when we register one route with multiple methods or some strange edge-cases
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.
It's here: #2435
We could create a getter in the request for a limited set of data: URL, method.. nothing more
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'll try to remember why I say that but right now it seems odd 😅
Because if you are in a handler, the routing succeed and the request method will be equals to the context as you said.
The only utility seems to be a shortcut
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.
@Eomm Should I keep it just in case or remove?
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.
lgtm
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.
LGTM
I think we need to add these methods to docs.
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.
LGTM
This would nicely solve #2143 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.
LGTM with the addition to 404 handler
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.
Almost forgot, we are adding the context
object to reply as well, which also contains .request
.
Can you make reply.context
a getter? This should save us some memory allocation.
@delvedor Replaced reply instance with getter, even though that particular change ended up being more invasive than I would like it to be; would appreciate if you could review that whole batch. |
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.
LGTM
@@ -484,8 +491,8 @@ function fastify (options) { | |||
|
|||
childLogger.info({ req }, 'incoming request') | |||
|
|||
const request = new Request(id, req, null, childLogger) |
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 parameters were wrong here to begin with, second arg is params
, not req
, but please double-check if this change makes sense.
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 you are right and we should improve this test because it is not checking it:
fastify/test/router-options.test.js
Line 63 in e70fd41
test('Should honor frameworkErrors option', t => { |
(in this PR or opening a new issue)
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.
@Eomm I would prefer not to increase scope of this PR further, and handle it in a separate PR.
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.
LGTM
@mcollina When do we plan to cut the next telease? |
We tend to ship Mondays or Tuesdays if there is something to ship. |
@mcollina Are we shipping today? |
Shipped v3.3.0 |
this.id = id | ||
this.context = context |
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.
Ooofff. It took me a while to figure out that the public API had changed when all of a sudden my decorator started failing nodeshift/faas-js-runtime@81a94e1. I guess since the change here was additive it wouldn’t normally qualify as a major version bump, but something to consider in the future when changing the public interface.
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.
Good spot, sorry for the incovenience.
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 worries - my stuff here is all R&D still, so things break ALL THE TIME. 👍
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.
same here. Please can we get the doc updated with this new prop in request?
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.
same here. Please can we get the doc updated with this new prop in request?
PRs are welcome.
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.
PRs are welcome.
@jsumners I took a brief look at the code and it seems that Request#context
is an instance of Context
.
Lines 233 to 247 in 9d703b0
const context = new Context( | |
opts.schema, | |
opts.handler.bind(this), | |
this[kReply], | |
this[kRequest], | |
this[kContentTypeParser], | |
config, | |
opts.errorHandler || this[kErrorHandler], | |
opts.bodyLimit, | |
opts.logLevel, | |
opts.logSerializers, | |
opts.attachValidation, | |
this[kReplySerializerDefault], | |
opts.schemaErrorFormatter || this[kSchemaErrorFormatter] | |
) |
This object is not currently in the API docs. Do you suggest that the entire Context
object be documented as part of the public API? Or instead, simply document portions of request.context
that are relevant to a user. When I search the current docs for "context", I only find it mentioned in passing as a part of the Reply
object.
https://github.com/fastify/fastify/blame/main/docs/Reply.md#L68-L76
It's odd, because the purpose of this PR seems to be solely about exposing routerPath
, routerMethod
and is404
getter properties on Request
by proxying these to the context
.
It's just a side effect that a context
instance is now part of the public API, and I wonder if that's really what is intended since this PR did actually document what the expected API changes were. If it's intended, it's not clear what of the Context
object should be publicly documented. If it's unintended, then it perhaps should not be documented? 🤷
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 confused. This PR is merged and has doc changes that show the properties added in the request documentation. What is missing in the live docs?
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.
@jsumners that was my question! It's not clear... This change introduced a context
property on the Request
object. But that was not the intent of the change, and so was never documented. Back in September, when I upgraded to a version containing this change, my application broke because of this new, undocumented property. When I figured out what had happened, I came here to mention it. Three days ago, someone else came here to mention the same thing and asked for doc changes. Then you said PRs are welcome, so I figured I would do my part and look into it. But, as I've said, it's not clear what exactly should be done.
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.
It's sort of documented under https://www.fastify.io/docs/latest/Routes/#config
@mcollina posted some reasoning in another PR discussion around why we don't fully document it. But I don't recall which.
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.
See #2989
Many of the other properties in fastify use a Symbol as the property key in order to essentially hide these properties, preventing them from becoming a part of the published API. The `context` property on `request` was essentially an undocumented breaking change to the API. See: fastify#2506 This commit removes the `context` property from `Request` and replaces it with a `Symbol` to both revert this breaking change, and to remove the `context` property from the API surface area. This is potentially a breaking change, however, the `Request#context` property has never been documented, and is - based on my understanding of the intent in fastify#2506 - not meant to be a part of the public API.
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. |
fixes #2435
fixes #2143
Checklist
npm run test
andnpm run benchmark
and the Code of conduct
Benchmarks:
After change: 148k requests in 5.12s, 27.6 MB read
Before change: 146k requests in 5.12s, 26.8 MB read