Nest is a scalable framework for building server-side applications. It is authored in TypeScript and relies on the Express framework. It leans heavily on modern language features such as async/await and decorators to reduce cruft and place the focus cleanly on route-handling business logic.

What is it like to work with Nest?

Server-side frameworks like Express and Connect are often very procedural and provide only a minimal set of support to move a request through to your routes. Nest takes a different approach by offering an opinionated pattern for developing applications. Common patterns like filtering routes or transforming data are done outside of the route-handling logic and connected using decorators, leaving the code well compartmentalized and easy to read. Decorators are also used to provide metadata to the framework on how routes get handled and what data the route handler receives. Finally, Nest provides an injector that supports values and factories that will inject data into components when they get constructed.

How is a Nest application structured?

Nest features get organized into groups of functionality held together by a Module. The top-level module is called the Application Module (or root module). Modules typically hold metadata that define the controllers and components that exist without that block of code. A module can also define components to be imported or exported to and from the injection scope.

Controllers get authored as objects that handle actions for a specified route. The controller’s methods are decorated to describe what actions they handle and how the data should be transformed and presented to the controller. It is then up to the controller to process the data and return a response, which will be automatically stringified and returned to the client as JSON. Or if something went wrong, an HTTPException can the thrown to return a non-200 status.

Finally, components are simply objects that get injected into a controller or other components. They can be anything, such as a service, a factory, a helper, etc. They often persist state or data for your application in one way or another.

A Basic Example

Let’s take a look at a fundamental Hello World Nest application. This application consists of a top-level module that defines a component and a controller. The HelloController handles GET requests and returns a simple message and accepts data from a POST request to update the message. The HelloService keeps a simple, universal reference to the thing we’re greeting. It is injected automatically to the HelloController via the constructor.

import { Module } from '@nestjs/common';
import { HelloController } from './HelloController;
import { HelloService } from './HelloService;

@Module({
    controllers: [ HelloController ],
    components: [ HelloService ]
})
export class HelloModule { }

The controller is responsible for handling routes and returning a response.

import { Body, Controller, Get, Post } from '@nestjs/common';
import { HelloService } from './HelloService;

@Controller('hello')
export class HelloController {
    constructor(private readonly helloService: HelloService) { }

    @Get()
    getGreeting() {
        const thing = this.helloService.get();
        return `Hello, ${ thing }`;
    }

    @Post()
    setGreeting(@Body() thing: string) {
        return this.helloService.set(thing);
    }

Components are just classes that provide functionality. The HelloService persists the “thing” we use in getGreeting().

import { Component, HttpException } from '@nestjs/common';

@Component()
export class HelloService {
    private thing = ‘World’;

    get() {
        return this.thing;
    }

    set(thing: string) {
        this.thing = thing;
    }
}

Should I use Nest?

Nest provides an excellent environment for creating server-side applications. Any team using TypeScript or starting a new project should strongly consider writing their next service using it. The benefits that Nest offers through its decorators, injector, and support via types are significant. And since the framework is built on Express and provides access to Express/Connect style middleware you can always fall back to handle rogue corner cases or integrate solutions from the deep pool of already existing Express middleware.

We’ve just touched upon the most common ways of using Nest. Beyond the core framework, Nest offers many advanced features including its microservice framework (for writing applications using other protocols like TCP) and WebSockets extensions. Nest is a robust and mature server-side framework authored in TypeScript and is worth consideration for your next project.