Get started with validation in Node.js

5 min read

The first step in putting together request validation for your Node.js application is finding a way to create flexible validation rules. When you try to pick a validation library to use, it’s often more difficult than you expect. They’re all different from each other, and it’s not clear what benefits one has over another.

Perhaps you’ve tried to build your own custom validation before, but it starts to feel messy and difficult to maintain. You want to put some reliable validation in place and move on to building exciting new features in your application. Why is adding in validation such a headache?!

In this article we’re going to learn how the JSON Schema specification can help us create flexible validation rules. We’ll write a schema which describes the format we expect data to be in, then we’ll use the Ajv validator library to validate our data against it.

Let’s get started!

A powerful validation duo

The JSON Schema specification defines a JSON-based format for describing the structure of JSON data. This includes validation keywords, such as type, required and properties. These keywords allow us to create a definition of the format we expect data to be in. This is a "schema". It can be as simple as:

{ "type": "string" }

To validate data against a schema, we need to use a validator library which implements the JSON Schema specification. The Ajv (Another JSON Schema Validator) library is the most popular JSON Schema validator for client and server side JavaScript, downloaded over 50 million times every week from npm.

Let’s get hands-on and see what validating data with JSON Schema and Ajv looks like.

Creating a schema and validating data

First we need to run the command npm install ajv to install the Ajv library.

Then we can jump straight into defining a JSON schema. It describes the structure and types we expect:

const iceCreamSchema = {
  type: "object",
  properties: {
    flavour: { type: "string" },
    price: { type: "number" },
    stock: { type: "number" },
  required: ["flavour", "price", "stock"],

Now we’ll define the data which we want to validate:

const iceCreamData = {
  flavour: "Pistachio",
  price: 1.99,
  stock: null,

Then we’ll import the Ajv library and create a new Ajv instance:

import Ajv from "ajv";

const ajv = new Ajv();

And use it to validate the data against our schema:

const isDataValid = ajv.validate(iceCreamSchema, iceCreamData);

Lastly, we’ll add some code to handle the validation results:

if (isDataValid) {
  console.log("The ice cream data is valid! 🍨");
} else {
  console.error("The ice cream data is invalid:", ajv.errors);

When we put this code together and run it, we get the following output:

The ice cream data is invalid: [
    instancePath: '/stock',
    schemaPath: '#/properties/stock/type',
    keyword: 'type',
    params: { type: 'number' },
    message: 'must be number'

Pretty slick, huh?

Alright, we’ve created a schema which describes the structure and types we expect, validated data against it, and handled any validation errors. So far so good!

As one final step, we’ll look at how we can potentially improve the way we create our JSON schema.

Schema generation

JSON schemas are an expressive way of defining validation rules, but writing schemas "by hand" can sometimes get a bit much. There’s a handy library called fluent-json-schema which can help us generate our JSON schemas. Let’s give it a try.

First we need to install the library by running the command npm install fluent-json-schema. Then we can import it and use it to generate our schema:

import S from "fluent-json-schema";

const iceCreamSchema = S.object()
  .prop("flavour", S.string().required())
  .prop("price", S.number().required())
  .prop("stock", S.number().required())
  // This method call returns the generated schema as an object.

If we console.log the iceCreamSchema object, we can see the JSON schema we’ve generated:

  $schema: "",
  type: "object",
  properties: {
    flavour: { type: "string" },
    price: { type: "number" },
    stock: { type: "number" },
  required: ["flavour", "price", "stock"],

You’ll notice this generated schema is almost identical to the iceCreamSchema we previously wrote "by hand". We can replace our hand crafted schema with this generated schema and the validation will behave in the same way as it did before.

If we’re writing our applications in TypeScript, the TypeBox library is a great alternative to fluent-json-schema.

Schema generation is down to your personal preference: some folks like to write raw JSON schemas "by hand", whereas others prefer to use a library which helps generate them. Try out both and pick whichever approach works best for you.

Try it yourself

Wrapping up

We can use Ajv as a standalone library or we can integrate it with the framework we’re using to build our Node.js application. Some Node.js frameworks even provide JSON Schema based validation with Ajv built in.

When we combine JSON Schema and Ajv, we have a flexible solution for implementing validation in our Node.js applications:

  • Learn once, use everywhere. The JSON Schema specification is cross-platform, and there are validation libraries available for every popular programming language. We’re not locked in to a library, framework or language. Once we’ve learnt the fundamentals of JSON Schema, we can use it everywhere.
  • Portability. Because JSON Schema is cross-platform, even if we decide to rewrite our applications in another framework or language, we can take our schemas with us.
  • Speed. Under the hood, Ajv compiles our JSON schemas into JavaScript code. This improves the performance of repeated validation of data against a schema. For example, schemas can be compiled by Ajv when our Node.js application starts. HTTP request data which the application receives can then be validated against the pre-compiled schemas.
  • Active and supportive community. There’s an active community of folks on Slack who are happy to help out (the JSON Schema website has a link you can use to join).

Further reading

If you’d like to learn more about JSON Schema, you might find these links helpful:

🧑‍💻 Node Validation Essentials workshop

Your Node.js applications can’t trust the data they receive. You might have created the best Node.js application ever made, but if the data going in is garbage, its going to crash. And that bad data could lead to lost sales and bad business decisions. It really is a case of garbage in, garbage out. The thing is, adding validation to your applications sucks: it feels complicated and overwhelming.

Imagine being known by your team as the developer who builds rock solid, reliable applications? You could sleep easy at night, knowing that your Node.js applications are robust and secure.

With the data your Node.js applications receive, it should be a case of guilty until proven innocent! If you want to sleep easy at night, and learn how to skillfully apply the essentials of request validation in Node.js:

Secure your seat for my Node Validation Essentials workshop at 20% off with the discount code EARLYBIRD.

Leave a Reply

Your email address will not be published. Required fields are marked *