2 · Data and boundaries · 30 MIN
Nest modules, controllers and providers
Controllers translate HTTP while providers own reusable behavior.
Nest uses modules to register controllers and providers in a dependency-injection graph. A controller receives its service through the constructor instead of constructing it for every request. This separation lets a test replace the service with a controlled implementation. The default provider scope is shared for the application, so never put a particular user’s mutable session state in an ordinary singleton service. The array below is fixed public demonstration data and is not durable storage.
Register and import the module into the application.
Read the example
// courses.service.ts
import {Injectable} from '@nestjs/common';
@Injectable() export class CoursesService {list(){return [{id:'react',title:'React foundations'}]}}
// courses.controller.ts
import {Controller,Get} from '@nestjs/common';
import {CoursesService} from './courses.service';
@Controller('courses') export class CoursesController {
constructor(private readonly courses:CoursesService){}
@Get() list(){return this.courses.list()}
}
// courses.module.ts
import {Module} from '@nestjs/common';
import {CoursesController} from './courses.controller';
import {CoursesService} from './courses.service';
@Module({controllers:[CoursesController],providers:[CoursesService]}) export class CoursesModule {}Check the expected output
After importing CoursesModule into AppModule, GET /courses returns the public course array.
Your challenge
Add a find-by-ID service method, return a 404 for unknown IDs and test the controller with a stubbed service.
Solution cost: O(n) teaching-array lookup; list construction is proportional to output. time · O(n) public result data. space
Common trap
Unregistered providers cannot be injected simply because their class exists.
Study the project implementation
// courses.service.ts
import {Injectable} from '@nestjs/common';
@Injectable() export class CoursesService {list(){return [{id:'react',title:'React foundations'}]}}
// courses.controller.ts
import {Controller,Get} from '@nestjs/common';
import {CoursesService} from './courses.service';
@Controller('courses') export class CoursesController {
constructor(private readonly courses:CoursesService){}
@Get() list(){return this.courses.list()}
}
// courses.module.ts
import {Module} from '@nestjs/common';
import {CoursesController} from './courses.controller';
import {CoursesService} from './courses.service';
@Module({controllers:[CoursesController],providers:[CoursesService]}) export class CoursesModule {}Further reading: Official documentation
Next lesson: Nest DTOs and validation pipes →