Implementing a sane backend in Node.js using NestJS: Architecture

Piotr Jaworski
Jit Team
Published in
5 min readJun 2, 2021

Node.js has been gaining prominence in the last years — in the 2020 Stack Overflow Developer Survey, Node.js hit the top spot in web frameworks, libraries, and tools for the second time in a row among with a score of over 50%. Node.js is reported to be used in a range of endeavors, starting from todo apps and ending in corporate projects at Linkedin, Microsoft, or Netflix.

But what about back-end services? Quite frankly, that doesn’t say anything about how Node.js is used — and since it’s hard to imagine a modern front-end JavaScript project without using Node.js for tooling, it’s probably safe to assume that this is the most common use case.

“Orthodox” back-end developers tend to treat the back-end capabilities of Node.js with a grain of salt. That makes some sense, as Node has some limitations, of which the main one is probably the lack of multi-threading. It‘s probably not too clever to use Node for heavy computation; other than that — you’re good to go. Whether it’s an API or a server-side rendered web app (or better yet — a chat server, a chatbot, or a real-time application), Node.js has you pretty much covered. In our case, over the course of this series of articles, we’re going to implement an API for a SPA application written in React.js. Since we don’t want to develop another to-do app, but we’re too lazy, it’s going to be a backend for a draggable Kanban board. Let’s move on!

Photo by Devon Janse van Rensburg on Unsplash

The first choice that needs to be made is, of course, the Node.js framework that will be the core of the application. Over the years the most popular choices seem to be:

  • Express.js,
  • Koa.js,
  • Hapi.js,
  • Sails.js,
  • NestJS.

with Express.js bearing the palm of the most popular one. We’re not taking Meteor.js into account, as it’s obviously not meant for this kind of use or any less popular frameworks. In this case, we’re going to go with NestJS, for numerous reasons:

  • Express is a great framework and it’s definitely mature enough, but pretty much everything needs to be written from scratch or added from external libraries; apart from that, every single application for serving front-end files is written using Express — it’s time to do something different!
  • Koa shares the same idea (it’s actually built by the same team as Express as a kind of its natural evolution) but is even more lightweight — which is cool, but it’s not exactly what we wanted for this application,
  • Hapi is a step in the right direction, as it’s more opinionated, but it isn’t that fast and the developer experience isn’t great,
  • Sails is not really a great choice for an API behind a SPA app because of its MVC backbone,
  • NestJS, on the other hand, is just opinionated enough. A good example would be the ORM — NestJS provides nice defaults but also allows for customization. It also natively supports TypeScript, which is awesome and should always be used, period. As a bonus, NestJS is also kind of familiar-looking to some developers, particularly those experienced in Spring Boot or Angular (especially that it relies heavily on the Dependency Injection pattern).
Photo by Aaron Santelices on Unsplash

Now that the framework has been chosen, it’s time to decide on the rest of the stack. Since we don’t want to go full hipster and the nature of the data allows us to do so, we’re not going to go with a NoSQL database (although it’s perfectly possible, there is even a separate section in the docs about MongoDB and Mongoose integration) — we’ll just stick with a safe, fast, scalable and reliable solution, which in this case will be PostgreSQL.

Another thing that we need to decide on is the ORM. As mentioned before, NestJS comes with a couple of ORMs that it supports out of the box, namely TypeORM and Sequelize. It’s also pretty easy to integrate with Knex.js or Prisma, but in this case, we’re going to stick with one of the defaults — since we love TypeScript so much, it’s going to be TypeORM (as it’s the most mature ORM for TypeScript, and it’s heavily inspired by well-known solutions such as Hibernate or Entity Framework).

The last decision that needs to be made at this point is the one concerning tooling — and surprisingly, this is actually a decision that already has been made for us — NestJS comes with all the build tools already set up, including TypeScript, Prettier, and Eslint configs. That sounds pretty imposing, but it’s really not — it means that it’s not needed to waste time on reminding yourself (again) which packages to install to get those three set up together or what to put in the Eslint config file — it’s possible to start hacking away immediately! It’s also worth mentioning that NestJS, as a truly opinionated framework, comes with a pre-configured testing library (Jest) and exemplary unit test and end-to-end test files.

Photo by Natalino D'Amato on Unsplash

That wraps it up for today! Follow Jit Team or sign up for the newsletter below 👇 to be up to date with the latest stories!

This article is the first of the series about building a well-structured API in Node.js using NestJS and PostgreSQL:

I mentor software developers. Drop me a line on MentorCruise for long-term mentorship or on CodeMentor for individual sessions.

--

--