feat: expose validate/serialize functions through Request and Reply#3970
feat: expose validate/serialize functions through Request and Reply#3970mcollina merged 42 commits intofastify:mainfrom
Conversation
jsumners
left a comment
There was a problem hiding this comment.
I think we are adding more complexity that is a sibling feature to https://www.fastify.io/docs/latest/Reference/Server/#schemacontroller (i.e. the goal is already possible by a feature already included).
Well, is kinda possible by providing the SchemaController, as you can store the reference somewhere and just decorate the The only reason I didn't go in that way was because of the encapsulation, as one of the easiest ways to do so is just exposing the SchemaController and allowing the implementation to do whatever it wants with it. But stills, as Fastify allows to not only overwrite the controller within an encapsulated context but also at a route level, the number of combinations and cases increases. |
mcollina
left a comment
There was a problem hiding this comment.
Can you please add a unit test?
lib/context.js
Outdated
| this[kRouteByFastify] = isFastify | ||
|
|
||
| this[kRequestValidateWeakMap] = new WeakMap() | ||
| this[kReplySerializeWeakMap] = new WeakMap() |
There was a problem hiding this comment.
I don't think creating two WeakMaps for every route is a good idea. Use an LRU that sits in the Fastify instance instead.
There was a problem hiding this comment.
Good point, but wouldn't that make the things a little bit more complicated as we'll need to bring a good default for customising the LRU cache size for cache eviction?
I support not building a WeakMap for every route as is possible the implementation is not going to use the serialize/validate feature for that specific route so doesn't have any sense to add it. Maybe we can go with a more conservative approach by lazy loading the WeakMap just if we detect usage, wdyt?
lib/reply.js
Outdated
| if (serialize == null) throw new FST_ERR_MISSING_SERIALIZATION_FN(httpStatus) | ||
| } else { | ||
| // Check if serialize function already compiled | ||
| if (this.context[kReplySerializeWeakMap].has(schema)) { |
There was a problem hiding this comment.
Using an object as a key will cause bugs: developers could change the object post-fact and it will cause problems. You need some sort of deep-equality-hashing for this.
I use http://npm.im/safe-stable-stringify for these kind of purposes. However generating the hash has a cost too.
There was a problem hiding this comment.
Maybe we can bring a middle ground solution? By dictating in the docs to not alter the original schema object but rather create a new one if there's a need to alter a schema on-the-fly?
Here the overhead of the hash is what worries me the most
|
Sorry for being like a ghost lately. Changed jobs, and laptop so I'm needing some time to setup everything once again. I hope to bring more activity to it by the end of the week 🙂 |
|
Just one though waiting for the docs: We could split the caching component into a separate PR. My doubt comes from the following example: the weakmap won't match and the schema will be always recompiled because the object is always a new one: The user should use this function like this to benefit from the weak map: This would ease the merge of this PR too I hope to see land it soo 😄 |
|
Sure! I think we can go and apply the suggestions from @mcollina and open a separate PR where we can discuss more in big detail an improvement in the shape of the caching, as because of what you already stated, it's easy for the user to implement it in such way that they will never benefit for the cache. I think as a first iteration just documenting what's the best approach can help to see how everything goes on a first run meanwhile improving that feature specific 🙂 Thankfully I'm free from Tomorrow on so I'll start adding the missed documentation, applying suggestions, and also adding the TS types. Sorry for the delay, has been a rough week. |
Co-authored-by: Manuel Spigolon <behemoth89@gmail.com>
|
Please feel free to have a look, I think is good to go in this state. Just the documentation is missed, I'll add it Tomorrow 🙂 |
|
CI is failing |
|
Coverage is low, let me take a look 👍 |
|
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 #3897
Pendings:
Checklist
npm run testandnpm run benchmarkand the Code of conduct