Building a Simple Service with Decorator-based Architecture in NestJS
📖 Scenario: You are creating a small NestJS service that manages a list of books. You will use decorators to define a service class and a method that returns the list of books.
🎯 Goal: Build a NestJS service class called BooksService using the @Injectable() decorator. Inside it, create a method getBooks() that returns an array of book titles.
📋 What You'll Learn
Create a class named BooksService.
Use the @Injectable() decorator on the BooksService class.
Inside BooksService, create a method called getBooks().
The getBooks() method should return an array of strings: ["The Hobbit", "1984", "Clean Code"].
💡 Why This Matters
🌍 Real World
Services in NestJS are used to organize business logic and data access. Using decorators like @Injectable() helps NestJS manage dependencies automatically.
💼 Career
Understanding decorator-based architecture in NestJS is essential for backend development roles using this popular framework. It helps build clean, maintainable, and testable server-side applications.
Progress0 / 4 steps
1
Create the BooksService class
Create a class called BooksService.
NestJS
Hint
Use the class keyword followed by BooksService and curly braces.
2
Add the @Injectable() decorator
Add the @Injectable() decorator above the BooksService class. Also, import Injectable from @nestjs/common.
NestJS
Hint
Place @Injectable() right before the class declaration.
3
Create the getBooks() method
Inside the BooksService class, create a method called getBooks() that returns the array ["The Hobbit", "1984", "Clean Code"].
NestJS
Hint
Define a method named getBooks() inside the class that returns the exact array.
4
Export the BooksService class
Ensure the BooksService class is exported using the export keyword so it can be used in other parts of the application.
NestJS
Hint
The class should already be exported with the export keyword before class.
Practice
(1/5)
1. In NestJS, what is the main purpose of using decorators like @Controller() and @Injectable()?
easy
A. To replace the need for writing any class methods
B. To execute the class methods automatically on app start
C. To mark classes with specific roles and add metadata for NestJS to manage
D. To style the output of the application in the browser
Solution
Step 1: Understand decorator roles in NestJS
Decorators like @Controller() and @Injectable() add metadata to classes, telling NestJS their purpose.
Step 2: Recognize how NestJS uses this metadata
NestJS uses this metadata to organize and manage components like controllers and services during runtime.
Final Answer:
To mark classes with specific roles and add metadata for NestJS to manage -> Option C
Quick Check:
Decorators add metadata = C [OK]
Hint: Decorators label classes for NestJS to organize [OK]
Common Mistakes:
Thinking decorators run methods automatically
Confusing decorators with styling tools
Believing decorators remove the need for methods
2. Which of the following is the correct way to define a controller class in NestJS using decorators?
easy
A. @Controller() class MyController { }
B. class MyController { }
C. function Controller() { } class MyController { }
D. @Injectable() class MyController { }
Solution
Step 1: Recall the syntax for controller decorators
In NestJS, the @Controller() decorator is placed immediately before the class definition.
Step 2: Check each option for correct decorator usage
@Controller() class MyController { } correctly shows @Controller() before the class. class MyController { } lacks any decorator. function Controller() { } class MyController { } incorrectly defines a function instead of using a decorator. @Injectable() class MyController { } uses @Injectable() which is for services, not controllers.
Final Answer:
@Controller() class MyController { } -> Option A
Quick Check:
Controller decorator before class = B [OK]
Hint: Controller classes need @Controller() decorator above class [OK]
Common Mistakes:
Omitting the decorator entirely
Using @Injectable() instead of @Controller()
Trying to define decorators as functions
3. Given the following NestJS controller code, what will be the output when a GET request is made to '/hello'?
The @Injectable decorator requires parentheses even if no arguments are passed, so it should be @Injectable().
Step 2: Verify other code parts
The method getUser() can be synchronous and return an object. Class name and return type are valid as is.
Final Answer:
Missing parentheses in @Injectable decorator -> Option B
Quick Check:
@Injectable() needs parentheses = D [OK]
Hint: Always add () after @Injectable even if empty [OK]
Common Mistakes:
Omitting parentheses on decorators
Thinking methods must be async
Changing class names unnecessarily
5. You want to create a NestJS controller that handles GET requests to '/users/:id' and returns the user ID from the URL. Which of the following code snippets correctly uses decorators to achieve this?
hard
A.
@Controller('users')
export class UserController {
@Get(':id')
getUser(id: string) {
return `User ID is ${id}`;
}
}
B.
@Controller('users')
export class UserController {
@Get()
getUser(@Body('id') id: string) {
return `User ID is ${id}`;
}
}
C.
@Controller('users')
export class UserController {
@Post(':id')
getUser(@Param('id') id: string) {
return `User ID is ${id}`;
}
}
D.
@Controller('users')
export class UserController {
@Get(':id')
getUser(@Param('id') id: string) {
return `User ID is ${id}`;
}
}
Solution
Step 1: Identify the correct HTTP method and route parameter usage
The route is '/users/:id' and should respond to GET requests, so @Get(':id') is correct.
Step 2: Check parameter decorator usage
The method parameter must use @Param('id') to extract the 'id' from the URL path.
@Controller('users')
export class UserController {
@Get(':id')
getUser(@Param('id') id: string) {
return `User ID is ${id}`;
}
}
does this correctly.
Step 3: Verify other options
@Controller('users')
export class UserController {
@Get()
getUser(@Body('id') id: string) {
return `User ID is ${id}`;
}
}
uses @Body('id') which reads from request body, not URL.
@Controller('users')
export class UserController {
@Post(':id')
getUser(@Param('id') id: string) {
return `User ID is ${id}`;
}
}
uses POST instead of GET.
@Controller('users')
export class UserController {
@Get(':id')
getUser(id: string) {
return `User ID is ${id}`;
}
}
misses the @Param decorator, so 'id' won't be injected.
Final Answer:
The code snippet with @Get(':id') and @Param('id') -> Option D
Quick Check:
GET + @Param('id') for URL param = A [OK]
Hint: Use @Get(':id') and @Param('id') to get URL parameters [OK]
Common Mistakes:
Using @Body instead of @Param for URL params
Using wrong HTTP method decorator
Forgetting @Param decorator on method argument
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.