As an Angular developer, I have been looking for a backend framework that helped me to be as efficient as possible. I've tried a few different Node frameworks, but my new favorite is definitely NestJS. From the beginning, I felt right at home with the way NestJS encourages you to organize your code, including with modules, HTTP interceptors, pipes, and more. In this article, I'll talk about some of the basics of NestJS and what makes me like it so much as an Angular developer. In future articles, I'll talk about more specific things I've learned about Nest.
There are a lot of reasons to like Nest.js. It's a modern Node framework that can run on Express or Fastify, uses TypeScript, and uses modern testing technology. As an Angular developer, I felt right at home from the very beginning. Let's look at some of the reasons why it was so familiar:
As an Angular developer of 5+ years, I have become used to the idea of splitting my code up in modules by feature, and putting code related to that feature in the module's folder. Nest.js follows that same pattern. Let's say that you are creating endpoints to create, update, get, and delete blog posts. All these endpoints would likely start with
/post. The route definition, if we wrote it down, might look like this:
... POST /posts Create a post GET /posts Get a list of posts GET /posts/:id Get a post by its ID PATCH /posts/:id Update a post DELETE /posts/:id Delete a post ...
Each of these endpoints are related to each other, and would be placed inside a
PostsController in the
PostsModule. This allows you to split up your code related to feature and isolate it from changes elsewhere in your code. Another similarity to the structure of an Angular app is that data access, like reading and writing to a database, happen in a service. This keeps the focus of the controller on handling the request, and then passes the responsibility of getting the data off to another file. This separation of concerns has been something that I've really grown to enjoy over the years.
Just like there are pipes and interceptors in your Angular app, they exist in a Nest.js application. I can't tell you how handy this is when working with data coming from an application and before it's saved to the database, or how nice it is before sending the data back to the application that requested it. For example, I was working on a project that accepted phone numbers from a front end application to be stored in a database. However, I wanted to make sure that the only information stored in the phone number field was numbers. I didn't want dashes or parentheses. I created a pipe that looked at the object coming in, found the phone numbers, and then ran a
replace function on the string. This resulted in the phone number being digits only. I was able to do the same for social security numbers. This structure of using a pipe to manipulate data in some way was very familiar to me.
Interceptors in Nest.js can work the same way as they do in Angular as well. For example, you can use interceptors to make sure that incoming calls have a token and that it's valid. If so, the request is allowed through. Otherwise, It's rejected. Again, this is something that I'm familiar with from my time in Angular, and there was little to no overhead for learning the topic.
There are also some things that I've liked that have nothing to do with Angular. I really like TypeORM, which isn't Nest-specific but did come recommended through the official Learn NestJS course. Being able to communicate with a database but without having to know the dirty details of connecting, reading, and writing is really convenient.
Another thing I liked, and I mentioned before, is the use of
class-validator. These packages, when used in combination with TypeORM and the defining of DTOs and Entities, ensures that data that's sent to the application matches a certain predefined and expected pattern. If your
PersonDTO expects a
firstName and you don't provide it, Nest.js throws a
400 Bad Request response. The same thing happens if you pass a number instead of a string. This ensures that the calling application sends the right information each time and we don't have to guess on the backend.
The last thing I'll mention here is Swagger. Again, this is not unique to Nest.js, but Nest makes it really easy to implement and use. With very little effort, you can have Swagger docs for your API. It does a really good job at determining what should be output for a given endpoint, but you can also very easily customize the output. This is really handy if you're building a backend application that other people will consume. There's no need to manually update any documentation; Swagger will just do it for you automatically.
Nest.js is a great tool for building backend TypeScript APIs and applications. It's a convenient, modern product that is well used and well documented. It's fast, and fast to develop in. There is very little context switch for you to go from building the Angular app to building the backend for your Angular app. I know I will be looking for ways to use this in upcoming projects, and as I do I will definitely write more about it