🐱
Backend Framework · Arena

NestJS

100 challenges · 0 mastered

0%
Arena cleared
0/100 mastered Let's go 🚀
Answer

NestJS is a progressive Node.js framework for building efficient, scalable server-side applications using TypeScript. It is heavily inspired by Angular and uses the same core concepts like modules, decorators, and dependency injection.

💡 Simple Analogy

If Angular is the framework you use to build the front of a restaurant, NestJS is the same blueprint applied to the kitchen (the backend) -- same layout, same rules, just on the server.

Answer

By default NestJS uses Express as its HTTP server platform, but you can swap it for Fastify for higher performance. NestJS abstracts the platform so most of your code stays the same.

Code Example
import { NestFactory } from '@nestjs/core';
import { FastifyAdapter, NestFastifyApplication } from '@nestjs/platform-fastify';

const app = await NestFactory.create<NestFastifyApplication>(
  AppModule,
  new FastifyAdapter(),
);
💡 Simple Analogy

NestJS is the driver, and Express or Fastify is the car. You can change cars without learning to drive again.

Answer

You use the Nest CLI command 'nest new project-name', similar to how Angular uses 'ng new'. The CLI scaffolds a ready-to-run project with a sample module, controller, and service.

Code Example
npm i -g @nestjs/cli
nest new my-app
cd my-app
npm run start:dev
💡 Simple Analogy

Just like 'ng new' builds an Angular skeleton for you, 'nest new' builds a backend skeleton you can run immediately.

Answer

The entry point is main.ts, which uses NestFactory to create an application instance from the root module and starts listening on a port. It is the backend equivalent of Angular's main.ts that bootstraps the root module.

Code Example
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);
}
bootstrap();
💡 Simple Analogy

main.ts is the ignition key -- it starts the whole engine from the root module, exactly like Angular's bootstrap.

Answer

The core building blocks are Modules, Controllers, and Providers (services). Modules group related code, controllers handle incoming requests, and providers contain business logic.

💡 Simple Analogy

Modules are rooms, controllers are the receptionists taking requests, and providers are the workers doing the actual job behind the scenes.

Answer

A decorator is a special function prefixed with @ that attaches metadata to classes, methods, or parameters, telling NestJS how to treat them. NestJS uses the exact same TypeScript decorators concept as Angular.

Code Example
@Controller('users')
export class UsersController {
  @Get()
  findAll() {
    return [];
  }
}
💡 Simple Analogy

A decorator is a sticky label on a box that tells the warehouse 'this is fragile' or 'this goes to shipping' -- just like @Component or @Injectable in Angular.

Answer

Express is a minimal, unopinionated HTTP library, while NestJS is a full framework that adds structure, dependency injection, modules, and TypeScript support on top of Express. NestJS gives you architecture out of the box; Express leaves it to you.

💡 Simple Analogy

Express is a pile of LEGO bricks; NestJS is a LEGO kit with instructions and labeled bags so everyone builds the same way.

Answer

A controller is a class decorated with @Controller that handles incoming HTTP requests and returns responses. It defines routes and delegates business logic to services.

Code Example
@Controller('cats')
export class CatsController {
  @Get()
  findAll(): string {
    return 'This returns all cats';
  }
}
💡 Simple Analogy

A controller is the receptionist at a desk: it takes the request, figures out who should handle it, and hands back the reply.

Answer

You pass a path prefix to the @Controller decorator and a path to the HTTP method decorator. The final route is the prefix joined with the method path.

Code Example
@Controller('users')
export class UsersController {
  @Get('profile')
  getProfile() {
    return 'profile';
  }
}
// Maps to GET /users/profile
💡 Simple Analogy

The @Controller path is the street name and the @Get path is the house number -- together they form the full address.

Answer

NestJS provides @Get, @Post, @Put, @Patch, @Delete, @Options, @Head, and @All decorators. Each maps a method to the matching HTTP verb.

Code Example
@Post()
create() { return 'created'; }

@Delete(':id')
remove() { return 'deleted'; }
💡 Simple Analogy

These decorators are like signs on a door saying which kind of knock (GET, POST, DELETE) the room responds to.

Answer

You use the @Param decorator to extract values from the URL path. You can grab a single named parameter or the whole params object.

Code Example
@Get(':id')
findOne(@Param('id') id: string) {
  return `User ${id}`;
}
💡 Simple Analogy

@Param is like reading the table number off a customer's ticket so you know which table to serve.

Answer

You use the @Query decorator to extract query string values from the URL. You can read a specific key or the entire query object.

Code Example
@Get()
findAll(@Query('page') page: string) {
  return `Page ${page}`;
}
// GET /users?page=2
💡 Simple Analogy

Query params are the optional notes after the '?' -- like saying 'I want page 2' when asking for a list.

Answer

You use the @Body decorator to extract the parsed request body, usually typed with a DTO class. NestJS parses the JSON body automatically.

Code Example
@Post()
create(@Body() createUserDto: CreateUserDto) {
  return createUserDto;
}
💡 Simple Analogy

@Body is opening the package a customer mailed in and reading what's inside.

Answer

A provider is any class that can be injected as a dependency, such as services, repositories, or factories. Providers are marked with the @Injectable decorator and managed by Nest's IoC container.

Code Example
@Injectable()
export class CatsService {
  findAll() {
    return ['Tom', 'Felix'];
  }
}
💡 Simple Analogy

A provider is a worker the framework keeps on staff and hands to whoever needs them -- just like an Angular service.

Answer

It marks a class as a provider that can be managed and injected by Nest's dependency injection system. Without it, Nest cannot resolve the class as a dependency.

Code Example
@Injectable()
export class LoggerService {
  log(msg: string) {
    console.log(msg);
  }
}
💡 Simple Analogy

@Injectable is the badge that lets a worker into the building so the framework knows it can assign them to teams.

Answer

Controllers should stay thin and focus on handling requests, while services hold reusable business logic. This separation makes code testable, reusable, and easier to maintain.

Code Example
@Controller('cats')
export class CatsController {
  constructor(private catsService: CatsService) {}

  @Get()
  findAll() {
    return this.catsService.findAll();
  }
}
💡 Simple Analogy

The receptionist (controller) shouldn't cook the food -- they pass the order to the kitchen (service).

Answer

You declare the service as a constructor parameter, and Nest automatically provides an instance. This is the same constructor-based dependency injection used in Angular.

Code Example
constructor(private readonly usersService: UsersService) {}
💡 Simple Analogy

You just ask for the service in the constructor and the framework delivers it, like ordering a part and it arrives ready to use.

Answer

You add the provider to the 'exports' array of its module so other modules that import it can use it. Without exporting, the provider stays private to its own module.

Code Example
@Module({
  providers: [UsersService],
  exports: [UsersService],
})
export class UsersModule {}
💡 Simple Analogy

Exporting a service is like putting a tool on the shared shelf so other rooms can borrow it.

Answer

You add the provider class to the 'providers' array of the @Module decorator. Nest then makes it available for injection within that module.

Code Example
@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
export class CatsModule {}
💡 Simple Analogy

Listing a provider in 'providers' is like adding a worker to the room's staff roster.

Answer

A module is a class decorated with @Module that organizes related controllers, providers, imports, and exports into a cohesive feature unit. Every NestJS app has at least a root module.

Code Example
@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
export class CatsModule {}
💡 Simple Analogy

A module is a room that holds everything for one feature -- just like an Angular NgModule groups related components and services.

Answer

The root module, usually named AppModule, is the top-level module that Nest uses to build the application graph. It imports all feature modules.

Code Example
@Module({
  imports: [UsersModule, AuthModule],
})
export class AppModule {}
💡 Simple Analogy

The root module is the main floor plan that connects all the rooms together, like Angular's AppModule.

Answer

The @Module decorator accepts controllers, providers, imports, and exports. Controllers handle requests, providers are injectables, imports bring in other modules, and exports share providers.

Code Example
@Module({
  imports: [],
  controllers: [],
  providers: [],
  exports: [],
})
export class FeatureModule {}
💡 Simple Analogy

It's like a room's setup form: who works here (providers), who answers the door (controllers), which rooms we connect to (imports), and what we lend out (exports).

Answer

You export providers from one module and import that module into another. The importing module can then inject the exported providers.

Code Example
@Module({
  providers: [AuthService],
  exports: [AuthService],
})
export class AuthModule {}
💡 Simple Analogy

One room lends a tool by exporting it, and another room borrows it by importing the room -- like sharing Angular services across modules.

Answer

A feature folder usually contains a module file, a controller file, a service file, and a dto folder, plus optional entities. This keeps each domain self-contained and easy to navigate.

Code Example
users/
  users.module.ts
  users.controller.ts
  users.service.ts
  dto/create-user.dto.ts
  entities/user.entity.ts
💡 Simple Analogy

Each feature gets its own labeled drawer with everything it needs inside, instead of scattering files everywhere.

Answer

You add the module class to the 'imports' array of the @Module decorator. This makes the imported module's exported providers available.

Code Example
@Module({
  imports: [UsersModule],
  controllers: [OrdersController],
})
export class OrdersModule {}
💡 Simple Analogy

Importing a module is like connecting a hallway between two rooms so one can use what the other lends out.