Skip to content
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

feat: add routeSchema and routeConfig + switching context handling #4216

Merged
merged 18 commits into from Sep 27, 2022
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 4 additions & 6 deletions docs/Reference/Reply.md
Expand Up @@ -7,7 +7,6 @@
- [.statusCode](#statuscode)
- [.server](#server)
- [.header(key, value)](#headerkey-value)
- [set-cookie](#set-cookie)
Uzlopak marked this conversation as resolved.
Show resolved Hide resolved
- [.headers(object)](#headersobject)
- [.getHeader(key)](#getheaderkey)
- [.getHeaders()](#getheaders)
Expand All @@ -16,13 +15,13 @@
- [.trailer(key, function)](#trailerkey-function)
- [.hasTrailer(key)](#hastrailerkey)
- [.removeTrailer(key)](#removetrailerkey)
- [.redirect([code,] dest)](#redirectcode--dest)
- [.redirect([code ,] dest)](#redirectcode--dest)
- [.callNotFound()](#callnotfound)
- [.getResponseTime()](#getresponsetime)
- [.type(contentType)](#typecontenttype)
- [.getSerializationFunction(schema | httpStatus)](#getserializationfunction)
- [.compileSerializationSchema(schema, httpStatus)](#compileserializationschema)
- [.serializeInput(data, [schema | httpStatus], [httpStatus])](#serializeinput)
- [.getSerializationFunction(schema | httpStatus)](#getserializationfunctionschema--httpstatus)
- [.compileSerializationSchema(schema, httpStatus)](#compileserializationschemaschema-httpstatus)
- [.serializeInput(data, [schema | httpStatus], [httpStatus])](#serializeinputdata-schema--httpstatus-httpstatus)
- [.serializer(func)](#serializerfunc)
- [.raw](#raw)
- [.sent](#sent)
Expand Down Expand Up @@ -84,7 +83,6 @@ object that exposes the following functions and properties:
from Node core.
- `.log` - The logger instance of the incoming request.
- `.request` - The incoming request.
- `.context` - Access the [Request's context](./Request.md) property.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should kepp it right now

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also done in f3be7b5


```js
fastify.get('/', options, function (request, reply) {
Expand Down
7 changes: 4 additions & 3 deletions docs/Reference/Request.md
Expand Up @@ -35,6 +35,10 @@ Request is a core Fastify object containing the following fields:
- `connection` - Deprecated, use `socket` instead. The underlying connection of
the incoming request.
- `socket` - the underlying connection of the incoming request
- `routeSchema` - the scheme definition set for the router that is
handling the request
- `routeConfig` - The route [`config`](./Routes.md#routes-config)
object.
- [.getValidationFunction(schema | httpPart)](#getvalidationfunction) -
Returns a validation function for the specified schema or http part,
if any of either are set or cached.
Expand All @@ -48,9 +52,6 @@ Request is a core Fastify object containing the following fields:
schema and returns the serialized payload. If the optional
`httpPart` is provided, the function will use the serializer
function given for that HTTP Status Code. Defaults to `null`.
Eomm marked this conversation as resolved.
Show resolved Hide resolved
- `context` - A Fastify internal object. You should not use it directly or
Eomm marked this conversation as resolved.
Show resolved Hide resolved
modify it. It is useful to access one special key:
- `context.config` - The route [`config`](./Routes.md#routes-config) object.

### Headers

Expand Down
2 changes: 1 addition & 1 deletion fastify.js
@@ -1,6 +1,6 @@
'use strict'

const VERSION = '4.5.3'
const VERSION = '5.0.0-dev'
Uzlopak marked this conversation as resolved.
Show resolved Hide resolved

const Avvio = require('avvio')
const http = require('http')
Expand Down
5 changes: 3 additions & 2 deletions lib/contentTypeParser.js
Expand Up @@ -15,7 +15,8 @@ const {
kRequestPayloadStream,
kState,
kTestInternals,
kReplyIsError
kReplyIsError,
kRouteContext
} = require('./symbols')

const {
Expand Down Expand Up @@ -154,7 +155,7 @@ ContentTypeParser.prototype.run = function (contentType, handler, request, reply
rawBody(
request,
reply,
reply.context._parserOptions,
reply[kRouteContext]._parserOptions,
parser,
done
)
Expand Down
28 changes: 26 additions & 2 deletions lib/context.js
Expand Up @@ -12,7 +12,8 @@ const {
kContentTypeParser,
kRouteByFastify,
kRequestValidateWeakMap,
kReplySerializeWeakMap
kReplySerializeWeakMap,
kPublicRouteContext
} = require('./symbols.js')

// Objects that holds the context of every request
Expand Down Expand Up @@ -56,17 +57,40 @@ function Context ({
this[kFourOhFourContext] = null
this.attachValidation = attachValidation
this[kReplySerializerDefault] = replySerializer
this.schemaErrorFormatter = schemaErrorFormatter || server[kSchemaErrorFormatter] || defaultSchemaErrorFormatter
this.schemaErrorFormatter =
schemaErrorFormatter ||
server[kSchemaErrorFormatter] ||
defaultSchemaErrorFormatter
this[kRouteByFastify] = isFastify

this[kRequestValidateWeakMap] = null
this[kReplySerializeWeakMap] = null
this.validatorCompiler = validatorCompiler || null
this.serializerCompiler = serializerCompiler || null

// Route + Userland configurations for the route
this[kPublicRouteContext] = getPublicRouteContext(this)

this.server = server
}

function getPublicRouteContext (context) {
return Object.create(null, {
schema: {
enumerable: true,
get () {
return context.schema
}
},
config: {
enumerable: true,
get () {
return context.config
}
}
})
}

function defaultSchemaErrorFormatter (errors, dataVar) {
let text = ''
const separator = ', '
Expand Down
10 changes: 7 additions & 3 deletions lib/error-handler.js
Expand Up @@ -3,7 +3,11 @@
const statusCodes = require('http').STATUS_CODES
const wrapThenable = require('./wrapThenable')
const {
kReplyHeaders, kReplyNextErrorHandler, kReplyIsRunningOnErrorHook, kReplyHasStatusCode
kReplyHeaders,
kReplyNextErrorHandler,
kReplyIsRunningOnErrorHook,
kReplyHasStatusCode,
kRouteContext
} = require('./symbols.js')

const {
Expand All @@ -24,7 +28,7 @@ const rootErrorHandler = {
function handleError (reply, error, cb) {
reply[kReplyIsRunningOnErrorHook] = false

const context = reply.context
const context = reply[kRouteContext]
if (reply[kReplyNextErrorHandler] === false) {
fallbackErrorHandler(error, reply, function (reply, payload) {
try {
Expand Down Expand Up @@ -90,7 +94,7 @@ function fallbackErrorHandler (error, reply, cb) {
const statusCode = reply.statusCode
let payload
try {
const serializerFn = getSchemaSerializer(reply.context, statusCode)
const serializerFn = getSchemaSerializer(reply[kRouteContext], statusCode)
payload = (serializerFn === false)
? serializeError({
error: statusCodes[statusCode + ''],
Expand Down
24 changes: 13 additions & 11 deletions lib/handleRequest.js
Expand Up @@ -4,7 +4,8 @@ const { validate: validateSchema } = require('./validation')
const { hookRunner, hookIterator } = require('./hooks')
const wrapThenable = require('./wrapThenable')
const {
kReplyIsError
kReplyIsError,
kRouteContext
} = require('./symbols')

function handleRequest (err, request, reply) {
Expand All @@ -17,6 +18,7 @@ function handleRequest (err, request, reply) {

const method = request.raw.method
const headers = request.headers
const context = request[kRouteContext]

if (method === 'GET' || method === 'HEAD' || method === 'SEARCH') {
handler(request, reply)
Expand All @@ -33,10 +35,10 @@ function handleRequest (err, request, reply) {
) { // Request has no body to parse
handler(request, reply)
} else {
reply.context.contentTypeParser.run('', handler, request, reply)
context.contentTypeParser.run('', handler, request, reply)
}
} else {
reply.context.contentTypeParser.run(contentType, handler, request, reply)
context.contentTypeParser.run(contentType, handler, request, reply)
}
return
}
Expand All @@ -49,7 +51,7 @@ function handleRequest (err, request, reply) {
headers['content-length'] !== undefined
)
) {
reply.context.contentTypeParser.run(contentType, handler, request, reply)
context.contentTypeParser.run(contentType, handler, request, reply)
} else {
handler(request, reply)
}
Expand All @@ -62,9 +64,9 @@ function handleRequest (err, request, reply) {

function handler (request, reply) {
try {
if (reply.context.preValidation !== null) {
if (request[kRouteContext].preValidation !== null) {
hookRunner(
reply.context.preValidation,
request[kRouteContext].preValidation,
hookIterator,
request,
reply,
Expand All @@ -87,9 +89,9 @@ function preValidationCallback (err, request, reply) {
return
}

const result = validateSchema(reply.context, request)
const result = validateSchema(reply[kRouteContext], request)
if (result) {
if (reply.context.attachValidation === false) {
if (reply[kRouteContext].attachValidation === false) {
reply.send(result)
return
}
Expand All @@ -98,9 +100,9 @@ function preValidationCallback (err, request, reply) {
}

// preHandler hook
if (reply.context.preHandler !== null) {
if (request[kRouteContext].preHandler !== null) {
hookRunner(
reply.context.preHandler,
request[kRouteContext].preHandler,
hookIterator,
request,
reply,
Expand All @@ -123,7 +125,7 @@ function preHandlerCallback (err, request, reply) {
let result

try {
result = reply.context.handler(request, reply)
result = request[kRouteContext].handler(request, reply)
} catch (err) {
reply[kReplyIsError] = true
reply.send(err)
Expand Down