joi validator to use with @novice1/routing.
It provides a middleware that can validate req.params
, req.body
, req.query
, req.headers
, req.cookies
and req.files
against a schema using joi validation.
npm install @novice1/validator-joi
// router.ts
import routing from '@novice1/routing'
import { validatorJoi } from '@novice1/validator-joi'
export default const router = routing()
router.setValidators(
validatorJoi(
// Joi.AsyncValidationOptions
{ stripUnknown: true },
// middleware in case validation fails
function onerror(err, req, res, next) {
res.status(400).json(err)
}
// name of the property containing the schema
'schema'
)
)
// schema.ts
import Joi from 'joi'
import { ValidatorJoiSchema } from '@novice1/validator-joi'
import router from './router'
// schema for "req.body"
const bodySchema = Joi.object({
name: Joi.string().required()
}).required()
export const routeSchema: ValidatorJoiSchema = Joi.object().keys({
body: bodySchema
})
// or
/*
export const routeSchema: ValidatorJoiSchema = {
body: bodySchema
}
*/
// or
/*
export const routeSchema: ValidatorJoiSchema = {
body: {
name: Joi.string().required()
}
}
*/
import routing from '@novice1/routing'
import express from 'express'
import router from './router'
import { routeSchema } from './schema'
router.post(
{
name: 'Post item',
path: '/items',
parameters: {
// the schema to validate
schema: routeSchema
},
// body parser
preValidators: express.json()
},
function (req: routing.Request<unknown, { name: string }, { name: string }>, res) {
res.json({ name: req.body.name })
}
)
Data can be transformed with methods like Joi.string().trim()
and more.
req.query
being readonly, its tranformed values can be
retrieved from req.validated().query
.
For req.params
, req.body
, req.headers
, req.cookies
and req.files
, the tranformation is applied on them and req.validated()
can still be used if you prefer.
raw data | transformed | |
---|---|---|
params | req.params or req.validated().params |
|
query | req.query |
req.validated().query |
body | req.body or req.validated().body |
|
headers | req.headers or req.validated().headers |
|
cookies | req.cookies or req.validated().cookies |
|
files | req.files or req.validated().files |
/**
* Since express@5 and @novice1/routing@2, req.query is readonly.
* The parsed and validated result can be found by calling the function 'req.validated()'.
*/
router.get(
{
name: 'Main app',
path: '/app',
parameters: {
query: {
version: Joi.number()
}
}
},
function (req, res) {
res.json(req.validated?.<{ version?: number }>().query?.version)
}
)
Override the error handler for a route.
import routing from '@novice1/routing'
import router from './router'
const onerror: routing.ErrorRequestHandler = (err, req, res) => {
res.status(400).json(err)
}
router.get(
{
path: '/override',
parameters: {
// overrides
onerror
},
},
function (req, res) {
// ...
}
)