NestJS

NestJS is modeled after Spring Boot. It uses dependency injection, which is rare in javascript world.

It feels a lot heavier compared to Next.js.

Create a new project

NestJS provides a commandline tool, which can be installed via npm:

npm install -g @nestjs/cli

Now create a new project:

nest new nest-app
cd nest-app

Start the app:

npm run start:dev

Visit http://localhost:3000/

The Structure

Let take a loop at the generated files:

├── README.md
├── "nest-cli.json"
├── "package-lock.json"
├── package.json
├── src
│   ├── app.controller.spec.ts  is for testing
│   ├── app.controller.ts
│   ├── app.module.ts
│   ├── app.service.ts
│   └── main.ts
├── test
│   ├── "app.e2e-spec.ts"
│   └── "jest-e2e.json"
├── tsconfig.build.json
└── tsconfig.json

We can see three key components here, namely controller, service and module.

Controllers are responsible for handling incoming HTTP requests and returning appropriate responses. They act as the entry point for external interactions with the application. In app.controller.ts it just calls the servers.

import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get()
  getHello(): string {
    return this.appService.getHello();
  }
}

Services encapsulate the business logic of an application. In app.service.ts it returns a string. In real world, they should handle complex operations, data manipulation, and interactions with external resources. Put application logic in service also allows code reuse, it can be called from multiple controller.

import { Injectable } from '@nestjs/common';

@Injectable()
export class AppService {
  getHello(): string {
    return 'Hello World!';
  }
}

Modules are used to wire up the application. This feels a bit overengineered. Take a look at the content of app.module.ts:

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
  imports: [],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

Add a module

nest also do scaffolding, since there is some bioleplatte code need to be written.

To add a new module:

nest generate module cats
nest generate controller cats
nest generate service cats

It adds a new folder:

└── src
    └── cats
        ├── cats.controller.spec.ts
        ├── cats.controller.ts
        ├── cats.module.ts
        ├── cats.service.spec.ts
        └── cats.service.ts

It also updates app.module.ts.

In controller, the annotation @Controller('cats') decides this will be accessable under the path /cats, but there is no handler yet, let's add a method with the @Get() annotation:

import { Controller, Get } from '@nestjs/common';

@Controller('cats')
export class CatsController {
  @Get()
  findAll() {
    return 'This action returns all cats';
  }
}

Now visit http://localhost:3000/cats should return all cats.

That's it for the basics of nestjs, read the documentation for more.