Architecture Overview

A Nest app is a tree of modules, each holding controllers and providers connected by dependency injection.

Every Nest application is organized around three core concepts. Understanding how they relate is the key to the whole framework.

The three building blocks

  • Modules - containers that group related controllers and providers.
  • Controllers - receive HTTP requests and return responses.
  • Providers (services) - hold business logic and are injected where needed.

A request flows in through a controller, which delegates to a service, which may talk to a database. Nest wires these together for you through its dependency injection container.

NestJS architecture: client request flows through module, controller, service, and data layerClientModuleControllerroutesServicelogicDatabase
A request enters a controller, which delegates work to an injected service that talks to the database.

Everything hangs off a single root module (usually AppModule), which imports the feature modules that make up your app.

Example

Example · typescript
// app.module.ts - the root of the tree
import { Module } from '@nestjs/common';
import { UsersModule } from './users/users.module';

@Module({
  imports: [UsersModule],
})
export class AppModule {}

When to use it

  • A developer draws the NestJS module tree to explain to a new hire how AuthModule, UsersModule, and AppModule are wired together.
  • A team uses separate feature modules (OrdersModule, PaymentsModule) so each squad owns its folder without coupling to others.
  • An architect applies the module + provider pattern to keep database repositories out of controllers and testable in isolation.

More examples

Root AppModule wiring modules

Shows how AppModule imports a feature module, forming the top of the dependency tree.

Example · ts
import { Module } from '@nestjs/common';
import { UsersModule } from './users/users.module';

@Module({
  imports: [UsersModule],
})
export class AppModule {}

Feature module declaration

Illustrates a self-contained module declaring its own controller and provider — the standard NestJS unit of encapsulation.

Example · ts
import { Module } from '@nestjs/common';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';

@Module({
  controllers: [UsersController],
  providers: [UsersService],
})
export class UsersModule {}

Three-layer request flow

Traces the three-layer architecture: HTTP layer (controller), business layer (service), and data layer (provider/repository).

Example · ts
// Controller → Service → Repository
@Controller('users')
export class UsersController {
  constructor(private readonly svc: UsersService) {}

  @Get(':id')
  find(@Param('id') id: string) {
    return this.svc.findOne(+id);
  }
}

Discussion

  • Be the first to comment on this lesson.