Validating JSON input in Node.js & TypeScript and cover these validation scenarios with Unit Tests

In the previous post I’ve created a sample backend with Node.js and TypeScript that can store comments via a POST call on /comments. I included some standard error handling for incorrect JSON syntax, but it didn’t actually check if the fields defined in our interface existed and contained correct values. Let’s add some validation for that now. Also, add unit tests for all error scenarios we have covered so far, so that we don’t accidentally break these when we alter our code even more.

Grabbing the template from last blog post

If you didn’t follow the previous blog post, make sure you have:

On github, do a and then switch to the 1.5 tag by running:

Verify that it works:

  • Open a new terminal and run
  • Run
  • Run (the “; echo” is only needed in Linux to not mess up new lines in the terminal) and verify that you get a valid JSON response.

How to validate the fields in the request body?

In the previous post we already added JSON parsing which checks whether the request body contains valid JSON. But what happens if fields have an unexpected value or are missing? What happens if we just pass an empty object? Let’s try.

Right now we don’t use the parameters yet, so nothing happens:

In the log statement we can see that it couldn’t grab the nickname parameter in the console.log statement in index.ts:

You might write some basic validation like this in the CommentsController.ts:

But then you might want to add a check if the strings aren’t empty or too long. You can add some regular expression / regex to verify this, you can see my quick attempt here:

You can try it with curl:

If your request body grows with more fields, this if statements grows pretty big and becomes unreadable.

The class-validator library

An alternative to there big if statements with regular expression checks is to use the class-transformer and class-validator library.

You can install them with:

In the previous post, we created the Comments.ts file with the NewCommentRequest interface.

We can convert this interface into a class with validation decorators on the fields they belong to. For the message I used the same regular expression, but for the nickname I could use a couple of predefined decorators that are much easier to read than a regular expression would be:

Once you save this code in IntelliJ or WebStorm, you’ll get this error:

You need to enable experimental support for decorators in the tsconfig.json:

Start using the class-transformer and class-validator

See my implementation here in the CommentsController.ts:

If you now try to create a comment with a nickname that contains a non alphanumeric character like ‘@’, we’ll see that the validation library gives a nice descriptive error in the console log.

It will also warn you when you leave fields out.

Update: Filtering out arrays

Something I found out long after writing this blog. While class-validator does perfect validation on any JSON objects with curly braces , whenever you pass an array with blocks in it:

You will see this is also valid JSON and the validator will completely ignore it. We can solve it for now simply by verifying whether the req.body starts and ends with curly braces.

Abstracting this validation stuff away from the business logic

We created a custom error handler for the JSON parser in the second blog post outside our bussiness logic (the postComment function in the CommentsController.ts). I don’t really want this validation logic in the postComment function. I want the postComment function to only focus on “posting a comment”!

But isn’t this validation part tied to the NewCommentRequest class that was created for the postComment function only? Well yes, but we can solve this by creating a generic middleware function in the index.ts. I took inspiration from the example from this blog post. Alter your index.ts with the following code:

You can clean up the CommentsController.ts after this quite a bit:

Writing unit tests that cover the error scenarios

You’re not really going to test manually with the curl commands that invalid JSON or JSON with missing fields are still handled correctly every time you change code and update your npm libraries. I am going to show how to set up simple tests for this without explaining what every library does.

Install the following dependencies:

First add an export statement in the index.ts so we can easily use the server:

In the package.json you can add a test script:

Create a test file called CommentsController.test.ts in the same folder as the CommentsController.ts. I created one test for a successful call:

This test approach uses one server for all tests within a describe block. This only works if your server is stateless. If it starts to contain state (in memory or an external database) you have to make sure your read the documentation of Mocha on how to start the server before every test and shut it down after every test to avoid tests affecting each others results.

You can run the tests with Or in IntelliJ rightclick on the test in the file:

Let’s add another test with incorrect JSON syntax:

And one with a valid json request that is missing the nickname field, just to verify that our validation with decorators works:

You can now run all tests together with or launch it from IntelliJ/WebStorm:

That’s it for this post. You can download the full code from GitHub.

Java/TypeScript Developer. Interested in web/mobile/backend/database/cloud. Freelancing, only interested in job offers from employers directly. No middle men.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store