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 2 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, default to `null`.
Fdawgs marked this conversation as resolved.
Show resolved Hide resolved
- [.validate(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. Default to `null`.
Fdawgs marked this conversation as resolved.
Show resolved Hide resolved
- `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
.getSerializationFunction('body')
Copy link
Member

Choose a reason for hiding this comment

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

misprint: the serialization function

validate({ foo: 0.5 }) // false
```

See [.compilaValidationSchema(schema, [httpStatus])](#compileserializationschema)
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
See [.compilaValidationSchema(schema, [httpStatus])](#compileserializationschema)
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`.
Copy link
Member

Choose a reason for hiding this comment

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

Should it be a link?

Also this is cached by using a `WeakMap` for reducing compilation calls.
Fdawgs marked this conversation as resolved.
Show resolved Hide resolved

The optional paramater `httpPart`, if provided, is forwarded directly
Fdawgs marked this conversation as resolved.
Show resolved Hide resolved
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'
}
}
})
validate({ foo: 'bar' }) // true

// or

const validate = request
.compileSerializationSchema({
Copy link
Member

Choose a reason for hiding this comment

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

misprint: the serialization is not involved here and it returns a string

type: 'object',
properties: {
foo: {
type: 'string'
}
}
}, 200)
validate({ hello: 'world' }) // false
Copy link
Member

Choose a reason for hiding this comment

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

What about renaming it to validateInput? (as serializeInput)

We did not land this feature yet

Copy link
Member Author

Choose a reason for hiding this comment

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

Sure, I think it can follow the same pattern as with the serializeInput 👍

```

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 valiadtion functions based on the schema provided. If the
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
the compiled valiadtion functions based on the schema provided. If the
the compiled validation functions based on the schema provided. If the

schemas provided is mutated or changed, the serialization functions will not
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
schemas provided is mutated or changed, the serialization functions will not
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 serialization function, as the cache is based on
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
previously compiled serialization function, as the cache is based on
previously compiled validation function, as the cache is based on

the reference of the schema (Object) previously provided.

If there's a need to change the properties of a schema, always opt to create
a totally new schema (object), otherwise the implementation won't benefit from
the cache mechanism.
Fdawgs marked this conversation as resolved.
Show resolved Hide resolved

:Using the following schema as example:
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
:Using the following schema as example:
Using the following schema as an example:

```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
```

### .validate(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 provided, the `httpPart` parameter
will take presedence.

If there is not a valiodation function for a given `schema`, a new validation
function will be compiled forwarding the `httpPart` if provided.
Fdawgs marked this conversation as resolved.
Show resolved Hide resolved

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

// or

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

// or

request
.serializeInput({ hello: 'world'}, 'query') // false
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
.serializeInput({ hello: 'world'}, 'query') // false
.validateInput({ hello: 'world'}, 'query') // false

```

See [.compileValidationSchema(schema, [httpStatus])](#compileValidationSchema)
for more information on how to compile validation schemas.
2 changes: 1 addition & 1 deletion 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