hapi — Validate Request Headers With Joi

In an advanced development state, you want to make use of request headers and because you don’t blindly trust the incoming values, you also apply validation rules. With hapi, you’ve a framework that has validation built into its core and makes it easy to define rules for request headers and this tutorial walks you through the setup of request header validation.

A quick heads up before moving on. This hapi series includes tutorials on various topics. Check out the series overview and make progress with ease.

hapi Series Overview

Prepare Your Project and Install Joi

You’ll use the joi module from within hapi’s plugin ecosystem to validate selected fields within the request payload. Before defining the validation itself, you need to add joi as a dependency to your project:

npm i -S joi  

Once the installation finished successfully, your project is prepared to make use of joi for object validation.

Validate Request Headers Using Joi

Requests sent from clients (e.g. browsers or mobile apps) will always contain multiple request headers, like properties for user-agent, accept, accept-encoding, and many more. Of course, all the request headers have their specific need and are evaluated and used by different tools.

Let’s imagine the following scenario: you want to keep track of all the different applications, tools and libraries that clients use to request your API. That’s why you set a required rule for the user-agent header and only requests with a value for the user-agent header are allowed to access the given route. Your setup may look like the following code snippet:

server.route({  
  method: 'GET',
  path: '/',
  config: {
    handler: …,
    validate: {
      headers: {
        'user-agent': Joi.string().required()
      },
      options: {
        allowUnknown: true
      }
    }
  }
})

The important part is the config.validate.headers object that needs to be set to the fields that you want to apply validation. You’d expect the user-agent to be a string value and also force it to be required.

The additional options object besides headers softens the need to validate all fields that you might use. Without the option allowUnknown: true, the validation process wouldn’t finish successfully when sending other header fields besides the user-agent, because no other fields are allowed (by default).

The sending a basic GET request to a hapi server with the route from above using Postman results in a response like this:

{
  "statusCode": 400,
  "error": "Bad Request",
  "message": "\"cache-control\" is not allowed. \"postman-token\" is not allowed. \"accept\" is not allowed. \"host\" is not allowed. \"accept-encoding\" is not allowed. \"connection\" is not allowed",
  "validation": {
    "source": "headers",
    "keys": [
      "cache-control",
      "postman-token",
      "accept",
      "host",
      "accept-encoding",
      "connection"
    ]
  }
}

Especially for request header validation it’s beneficial to allow unknown properties, because you can’t have a proper validation rule in place for all the different options out there. Make sure to validate the headers that you’re using within your application and the rest is walking through your app without further notice.

Outlook

Within this tutorial, you’ve seen the setup to validate request headers on a given route. And besides the validation, you know how to allow unknown properties even though you’ve a single or multiple validation rules in place.

We’re happy to hear your thoughts and comments. Please don’t hesitate to use the comments below or find us on Twitter @futurestud_io. Let us know what you think!

Enjoy coding & make it rock!

Explore the Library

Find interesting tutorials and solutions for your problems.