How to validate Node + Express requests with Joi middleware
Tags: javascript, node, express, joi
Published: 2024-05-14 09:29:23

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](https://github.com/hapijs/joi).

In this article i would like to make use of my new middleware [express-joi-validations](https://github.com/mattiamalonni/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:

```javascript
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](https://github.com/mattiamalonni/express-joi-validations) middleware.

The output would be something like this:

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

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

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

```javascript
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](https://github.com/mattiamalonni/express-joi-validations)
For any question feel free to ask in the comments section below or in DM.