Let a Node.js backend consume and produce JSON

The first thing you want to do after creating a hello world REST service using TypeScript, Node.js and Express.js is figure out how to let it consume and produce JSON.

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.2 tag by running:

Verify that it works:

  • Run:
  • Open a new terminal and run:
  • Run:
  • Browse to http://localhost:8080/ and it should say “”Hello Leon!” or whatever name you entered when following the previous post.

So what do we want to produce and consume?

We will create a sample endpoint on localhost:8080/comments, on which we can do a POST request with JSON in the body to store a comment. The response body will contain the newly generated comment id and timestamp. Normally a comment would be stored in a database so we can retrieve the comment later via GET requests, but let’s leave that out for now (maybe for a future blog post? I need to test the Firebase API anyway).

Restructuring the project

Besides the existing index.ts in our ‘src’ folder, I’d recommend creating a folder for the controller and one for the model:

Creating a request handler function

Right now we have a request handler in the index.ts itself, but I think it’s nice to put request handlers in a separate file. Create a CommentsController.ts file in a controller directory. Put a function there with a fitting name for storing a comment:

Now we need to tell Express to forward POST requests on /comments to this new function.

Defining interfaces for the request and response

Below is what first came to my mind. I’d create a Comment.ts file in the model directory that exports these interfaces.

Using the interfaces to consume and produce JSON

So let’s do a very basic implementation in the CommentsController.ts that doesn’t really do anything with the request, but parses it and responses with a valid CommentConfirmation:

To test this you can use curl:

Or via Postman:

Error scenarios

So let’s take a look what happens if somebody sends incorrect JSON, for example by removing the first curly brace of the request body:

On the server logs you’ll see this:

If you want to test this using curl:

What happened?

This is caused by the code we added to index.ts in the previous step:

This added a handler that started to parse the bodies of incoming requests to JSON. The default behavior for incorrect JSON syntax seems to be to return a response with HTTP status 400 and the stacktrace in the body, while also printing the stacktrace in your server log.

While this is an acceptable default for proof of concepts, this is undesired in production environments behavior for two reasons:

  • Information leakage. My project is open source so it doesn’t really bother me that the client receives my stacktrace, but companies with closed source software often don’t want to expose this information to potential attackers.
  • It spams your log file. If you write the front end that makes requests to your backend you should make sure it always sends valid JSON. If people ignore your frontend and start sending invalid syntax on their own via curl or Postman, you mostly don’t care about the detailed stacktrace it caused. You are more interested in what they did send.

The quick and easy solution

The solution that the official Express.js documentation and stackoverflow seem to recommend is to write a custom error handler. Therefore it’s probably a best practice. I found a simpler solution though. OliverJAsh on GitHub suggested just parsing the requests as text and parsing JSON in the POST function itself. This way you have full control.

In index.ts, replace this line:

By:

Now simply wrap the JSON.parse() method around the req.body in the CommentsController:

If you find yourself in a situation where you get lots of “Invalid Requests” in your server logs and you don’t know what’s causing this. You can log the request bodies in your catch clause to figure out what’s going wrong:

This will spam your logs with incoming request bodies, but will give you an idea of what incorrect JSON is coming in. I made a tag on GitHub for it so you can use the code with this “quick and easy” solution.

Creating our own Error Handler

In the situation above we handled the JSON parsing in the postComment function. But parsing the JSON and handling errors doesn’t really have anything to do with the business logic of the postComment function, which should be “to post a comment”. Let’s check this Stackoverflow answer on how you could handle the errors on a different way:

I recommend you to read the official Express documentation on Error Handling and creating your own error handler:

Let’s place an error handler like the one above in our index.ts file. Unfortunately TypeScript won’t accept these parameters if we do that.

TS7006: Parameter err’ implicitly has an ‘any’ type.

When using TypeScript, we need to define the types like this:

But even with the types defined in this error handler, it complains with

The status and body properties don’t seem to be defined in the type definitions of the SyntaxError. To solve this I created an interface that extends SyntaxError and defines the status and body fields. Next, I cast the ‘err’ object to a SyntaxErrorWithStatus object to validate the status.

After the casting I log the malformed body of the request that we tried to parse and send a response with the 400 status code.

You can test it again with the curl command:

The code

Find the complete code so far here on GitHub. Learn how to do additional validation on the incoming JSON in my third blog post here.

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