Validating inputs is one of the most important things you should do as a backend developer. No matter what language or framework you use, you must not trust user inputs, ever.
And when it comes to Node, there are a ton of libraries out there that enables you to achieve this result. One of them is, precisely, Joi.
In this article i would like to make use of my new middleware express-joi-validations to present a new way to validate user inputs in Express.
Suppose you have an endpoint for registering new user on /signup route, you would have something like this:
import express from 'express';
const app = express();
app.post('/signup', (request, response) => {
const { username, email, password } = request.body;
});
If you now want to validate that username, email and password meets your sing-up criteria, instead of using a bunch of if statements, you can use Joi with the help of express-joi-validations middleware.
The output would be something like this:
import express from 'express';
import { Joi, validateBody } from 'express-joi-validations';
const app = express();
const userSignUp = Joi.object({
username: Joi.string().required().trim().alphanum().min(3).max(30),
email: Joi.string().required().trim().email(),
password: Joi.string().required().min(8),
});
app.post('/api/users', validateBody(userSignUp), (request, response) => {
const errors = request.validationErrors.body;
if (errors) {
response.status(400).json({ error: 'Invalid user inputs' })
}
const { username, email, password } = request.validationValues.body;
});
As you can see, express-joi-validations exposes the method validateBody that you can use to validate the payload of the body and the validated data will be in the request.validationValues.body field.
If the input does not meet your criteria, the request.validationErrors.body field will be populated with an array of Joi errors that you can use to be more specific on what went wrong.
In addition to the validateBody method, you can use also the validateHeader method to validate request headers:
import { Joi, validateHeaders } from 'express-joi-validations';
const userToken = Joi.object({
authorization: Joi.string().required().regex(/^Bearer [A-Za-z0-9-_]+\.[A-Za-z0-9-_]+\.[A-Za-z0-9-_.+/=]*$/),
});
app.get('/api/secret', validateHeaders(userToken), (request, response) => {
// this area is restricted to registered users only
});
or the validateParams and validateQuery to validate url:
import { Joi, validateParams, validateQuery } from 'express-joi-validations';
// GET /posts/507f1f77bcf86cd799439011
const postId = Joi.object({
id: Joi.string().hex().length(24),
});
app.get('/posts/:id', validateParams(postId), (request, response) => {
const post = Post.findById(request.validationValues.params.id)
});
// GET /posts?page=2
const postQuery = Joi.object({
page: Joi.optional().number().integer().min(1).default(1),
});
app.get('/posts', validateQuery(postQuery), (request, response) => {
const posts = Post.findAll({ page: request.validationValues.query.page })
});
In addition to these helper methods, you can use the more generic validate to combine multiple validations together:
import { Joi, validate } from 'express-joi-validations';
app.put('/posts/:id', validate({ headers: userToken, params: postId, body: postBody }), (request, response) => {
// Validation errors will be in request.validationErrors
// Validation values will be in request.validationValues
});
That's it for this article.
For a better customization of the middleware, please refer to the official GitHub repository: https://github.com/mattiamalonni/express-joi-validations
For any question feel free to ask in the comments section below or in DM.
Top comments (0)