Skip to main content

The main parts of an application

A NestJS application consists of four main parts, which together form the framework's architectural frame. Each plays its own role in building logically isolated yet interconnected layers.

1. Modules

A module is a container that groups related elements of the application: controllers, services, filters, pipes, and so on. Every NestJS application always has at least one module - AppModule (the root one).

Example:

javascript
import { Module } from '@nestjs/common'; import { UsersModule } from './users/users.module'; import { AuthModule } from './auth/auth.module'; @Module({ imports: [UsersModule, AuthModule], }) export class AppModule {}

Role:

  • defines the boundaries of a feature;
  • encapsulates dependencies;
  • provides scalability (new modules can be added without rewriting old ones).

2. Controllers

Controllers accept incoming requests (e.g. HTTP requests) and return responses to the client. They define the routes (endpoints) and hand execution off to services.

Example:

javascript
import { Controller, Get } from '@nestjs/common'; import { UsersService } from './users.service'; @Controller('users') export class UsersController { constructor(private readonly usersService: UsersService) {} @Get() findAll() { return this.usersService.findAll(); } }

Role:

  • the entry point for requests (HTTP, WebSocket, GraphQL, etc.);
  • holds no business logic, just routing and passing data to services.

3. Providers

A provider is any entity that can be injected via Dependency Injection. The most common example is a service, which holds the business logic.

Example:

javascript
import { Injectable } from '@nestjs/common'; @Injectable() export class UsersService { private users = [{ id: 1, name: 'Alex' }]; findAll() { return this.users; } }

Role:

  • implements the business logic;
  • supplies data and functionality to other classes;
  • managed by NestJS's DI container.

4. Decorators

Decorators are NestJS's key feature, letting you write declarative, readable code. They add metadata so Nest knows how to handle a class or method.

Examples of decorators:

DecoratorPurpose
@Module()describes a module
@Controller()defines a controller
@Injectable()marks a class as a provider
@Get(), @Post(), @Put()define HTTP routes
@Body(), @Param(), @Query()extract data from the request
@UseGuards(), @UseInterceptors()attach middleware-like mechanisms

Role:

  • they simplify the architecture, making the code declarative and self-documenting.

How the components relate to each other

javascript
[ Client ] [ Controller ] → receives the request [ Service / Provider ] → handles the data and business logic [ Module ] → manages dependencies and assembles the components [ Response to the client ]

Additional NestJS elements (supporting layers)

While the four main parts are the foundation, real applications often use other important components too:

ComponentDescription
PipesTransform and validate input data
GuardsControl access (e.g. authorization)
InterceptorsIntercept requests/responses, add extra logic
FiltersHandle errors
MiddlewaresRun before routing (e.g. logging)

A typical application's overall structure

javascript
src/ ├── app.module.ts ├── users/ │ ├── users.module.ts │ ├── users.controller.ts │ └── users.service.ts ├── auth/ │ ├── auth.module.ts │ ├── auth.controller.ts │ └── auth.service.ts └── main.ts ← the entry point (bootstrapping the application)

Summary

ComponentPurpose
ModuleGroups and manages dependencies
ControllerAccepts requests and sends responses
Provider (Service)Implements the business logic
DecoratorDefines components' behavior and structure

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.