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

refactor: rename request.validate to request.validateInput #4139

Merged
merged 7 commits into from
Jul 19, 2022
Merged
Show file tree
Hide file tree
Changes from 6 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
4 changes: 2 additions & 2 deletions docs/Reference/Reply.md
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ const serialize = reply
serialize({ foo: 'bar' }) // '{"foo":"bar"}'
```

See [.compileSerializationSchema(schema, httpStatus)](#compileserializationschema)
See [.compileSerializationSchema(schema, [httpStatus])](#compileserializationschema)
mcollina marked this conversation as resolved.
Show resolved Hide resolved
for more information on how to compile serialization schemas.

### .compileSerializationSchema(schema, httpStatus)
Expand Down Expand Up @@ -499,7 +499,7 @@ reply
.serializeInput({ foo: 'bar'}, 200) // '{"foo":"bar"}'
```

See [.compileSerializationSchema(schema, httpStatus)](#compileserializationschema)
See [.compileSerializationSchema(schema, [httpStatus])](#compileserializationschema)
mcollina marked this conversation as resolved.
Show resolved Hide resolved
for more information on how to compile serialization schemas.

### .serializer(func)
Expand Down
171 changes: 171 additions & 0 deletions docs/Reference/Request.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,19 @@ 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
- [.getValidationFunction(schema | httpPart)](#getvalidationfunction) -
Returns a validation function for the specified schema or http part,
if any of either are set or cached.
- [.compileValidationSchema(schema, [httpPart])](#compilevalidationschema) -
Compiles the specified schema and returns a validation function
using the default (or customized) `ValidationCompiler`.
The optional `httpPart` is forwarded to the `ValidationCompiler`
if provided, defaults to `null`.
- [.validateInput(data, schema | httpPart, [httpPart])](#validate) -
Validates the specified input by using the specified
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`.
- `context` - A Fastify internal object. You should not use it directly or
modify it. It is useful to access one special key:
- `context.config` - The route [`config`](./Routes.md#routes-config) object.
Expand Down Expand Up @@ -77,3 +90,161 @@ fastify.post('/:params', options, function (request, reply) {
request.log.info('some info')
})
```
### .getValidationFunction(schema | httpPart)
<a id="getvalidationfunction"></a>

By calling this function using a provided `schema` or `httpPart`,
it will return a `validation` function that can be used to
validate diverse inputs. It returns `undefined` if no
serialization function was found using either of the provided inputs.

```js
const validate = request
.getValidationFunction({
type: 'object',
properties: {
foo: {
type: 'string'
}
}
})
validate({ foo: 'bar' }) // true

// or

const validate = request
.getValidationFunction('body')
validate({ foo: 0.5 }) // false
```

See [.compilaValidationSchema(schema, [httpStatus])](#compilevalidationschema)
for more information on how to compile validation function.

### .compileValidationSchema(schema, [httpPart])
<a id="compilevalidationschema"></a>

This function will compile a validation schema and
return a function that can be used to validate data.
The function returned (a.k.a. _validation function_) is compiled
by using the provided [`SchemaControler#ValidationCompiler`](./Server.md#schema-controller).
A `WeakMap` is used to cached this, reducing compilation calls.

The optional parameter `httpPart`, if provided, is forwarded directly
the `ValidationCompiler`, so it can be used to compile the validation
function if a custom `ValidationCompiler` is provided for the route.


```js
const validate = request
.compileValidationSchema({
type: 'object',
properties: {
foo: {
type: 'string'
}
}
})
console.log(validate({ foo: 'bar' })) // true

// or

const validate = request
.compileValidationSchema({
type: 'object',
properties: {
foo: {
type: 'string'
}
}
}, 200)
console.log(validate({ hello: 'world' })) // false
```

Note that you should be careful when using this function, as it will cache
Copy link
Member

Choose a reason for hiding this comment

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

I wonder if we should just link a blog post (I volunteer to write it) to explain this.

I think it is too technical and the user may loose the focus on the "big picture"

Copy link
Member Author

Choose a reason for hiding this comment

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

Agree, didn’t find a way to make it less verbose. Actually I think a Blog post will explain pretty what’s about, happy to be part if I can be helpful somehow 🙂

the compiled validation functions based on the schema provided. If the
schemas provided are mutated or changed, the validation functions will not
detect that the schema has been altered and for instance it will reuse the
previously compiled validation function, as the cache is based on
the reference of the schema (Object) previously provided.

If there is a need to change the properties of a schema, always opt to create
a totally new schema (object), otherwise the implementation will not benefit from
the cache mechanism.

:Using the following schema as an example:
Fdawgs marked this conversation as resolved.
Show resolved Hide resolved
```js
const schema1 = {
type: 'object',
properties: {
foo: {
type: 'string'
}
}
}
```

*Not*
```js
const validate = request.compileValidationSchema(schema1)

// Later on...
schema1.properties.foo.type. = 'integer'
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
schema1.properties.foo.type. = 'integer'
schema1.properties.foo.type = 'integer'

Copy link
Member Author

Choose a reason for hiding this comment

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

Note for myself: Do not write documentation late in the night 😅

const newValidate = request.compileValidationSchema(schema1)

console.log(newValidate === validate) // true
```

*Instead*
```js
const validate = request.compileValidationSchema(schema1)

// Later on...
const newSchema = Object.assign({}, schema1)
newSchema.properties.foo.type = 'integer'

const newValidate = request.compileValidationSchema(newSchema)

console.log(newValidate === validate) // false
```

### .validateInput(data, [schema | httpStatus], [httpStatus])
<a id="validate"></a>

This function will validate the input based on the provided schema,
or HTTP part passed. If both are provided, the `httpPart` parameter
will take precedence.

If there is not a validation function for a given `schema`, a new validation
function will be compiled, forwarding the `httpPart` if provided.

```js
request
.validateInput({ foo: 'bar'}, {
type: 'object',
properties: {
foo: {
type: 'string'
}
}
}) // true

// or

request
.validateInput({ foo: 'bar'}, {
type: 'object',
properties: {
foo: {
type: 'string'
}
}
}, 'body') // true

// or

request
.validateInput({ hello: 'world'}, 'query') // false
```

See [.compileValidationSchema(schema, [httpStatus])](#compileValidationSchema)
for more information on how to compile validation schemas.
4 changes: 2 additions & 2 deletions lib/request.js
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ Object.defineProperties(Request.prototype, {
}
},
compileValidationSchema: {
value: function (schema, httpPart) {
value: function (schema, httpPart = null) {
const { method, url } = this

if (this.context[kRequestValidateWeakMap]?.has(schema)) {
Expand Down Expand Up @@ -259,7 +259,7 @@ Object.defineProperties(Request.prototype, {
return validateFn
}
},
validate: {
validateInput: {
mcollina marked this conversation as resolved.
Show resolved Hide resolved
value: function (input, schema, httpPart) {
httpPart = typeof schema === 'string' ? schema : httpPart

Expand Down