Bird
Raised Fist0
NestJSframework~10 mins

Decorator-based architecture in NestJS - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Decorator-based architecture
Define Class
↓
Apply Decorators
↓
NestJS Reads Metadata
↓
Build Dependency Graph
↓
Instantiate Classes with Injected Dependencies
↓
Run Application
This flow shows how NestJS uses decorators to mark classes and methods, reads metadata, builds dependencies, and runs the app.
Execution Sample
NestJS
import { Controller, Get } from '@nestjs/common';

@Controller('cats')
export class CatsController {
  @Get()
  findAll() { return 'All cats'; }
}
Defines a controller with a route using decorators to mark class and method for NestJS routing.
Execution Table
StepActionDecorator ProcessedMetadata AddedEffect
1Read @Controller('cats') on CatsController@ControllerRoute prefix 'cats' addedClass marked as controller with base route
2Read @Get() on findAll method@GetRoute GET '/' addedMethod marked as GET handler
3NestJS builds routing tableN/AController and routes registeredApp knows to call findAll on GET /cats
4App starts and listensN/AServer runningReady to handle requests
5Request GET /cats receivedN/ARoute matchedfindAll method called
6findAll returns 'All cats'N/AResponse generatedClient receives 'All cats'
7No more requestsN/AIdleWaiting for next request
💡 Execution stops when no more requests are received or app is stopped.
Variable Tracker
VariableStartAfter Step 1After Step 2After Step 3After Step 5Final
CatsController Metadata{}{ routePrefix: 'cats' }{ routePrefix: 'cats', routes: [{ method: 'GET', path: '/' }] }{ registered: true }{ registered: true, lastCall: 'findAll' }{ registered: true, lastCall: 'findAll', response: 'All cats' }
Key Moments - 3 Insights
Why does NestJS use decorators instead of normal functions?
Decorators add metadata to classes and methods that NestJS reads later to build routing and dependency injection, as shown in steps 1 and 2 of the execution_table.
How does NestJS know which method to call for a GET request?
The @Get decorator adds route info to the method metadata (step 2), which NestJS uses to match incoming requests to methods (step 5).
What happens if no decorator is used on a class?
Without decorators, NestJS does not register the class as a controller or provider, so it won't be part of the app's routing or dependency graph.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what metadata is added after step 2?
AServer starts listening
BRoute prefix 'cats' added to CatsController
CRoute GET '/' added to findAll method
DResponse 'All cats' generated
💡 Hint
Check the 'Metadata Added' column in row 2 of execution_table
At which step does NestJS register the controller and routes?
AStep 3
BStep 1
CStep 5
DStep 7
💡 Hint
Look for 'registered' status in the 'Effect' column in execution_table
If the @Get decorator is removed, what changes in the execution_table?
AStep 1 would fail to add route prefix
BStep 2 metadata would be missing, no GET route registered
CApp would not start at step 4
DResponse would still be 'All cats'
💡 Hint
Refer to step 2 where @Get adds route metadata
Concept Snapshot
Decorator-based architecture in NestJS:
- Use decorators like @Controller and @Get to mark classes and methods
- Decorators add metadata NestJS reads to build routing and DI
- NestJS creates instances and routes requests based on metadata
- This pattern keeps code clean and declarative
- Removing decorators means NestJS ignores those classes/methods
Full Transcript
In NestJS, decorators are special markers on classes and methods. When the app starts, NestJS reads these decorators to understand which classes are controllers and which methods handle routes. For example, @Controller('cats') marks a class as a controller with a base route 'cats'. The @Get decorator on a method marks it as a handler for GET requests. NestJS collects this metadata, builds a routing table, and when a request comes in, it calls the right method. This flow lets developers write clean code while NestJS handles wiring everything together.

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

  1. Step 1: Understand decorator roles in NestJS

    Decorators like @Controller() and @Injectable() add metadata to classes, telling NestJS their purpose.
  2. Step 2: Recognize how NestJS uses this metadata

    NestJS uses this metadata to organize and manage components like controllers and services during runtime.
  3. Final Answer:

    To mark classes with specific roles and add metadata for NestJS to manage -> Option C
  4. 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

  1. Step 1: Recall the syntax for controller decorators

    In NestJS, the @Controller() decorator is placed immediately before the class definition.
  2. 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.
  3. Final Answer:

    @Controller() class MyController { } -> Option A
  4. 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'?
@Controller('hello')
export class HelloController {
  @Get()
  greet() {
    return 'Hello, NestJS!';
  }
}
medium
A. "Hello, NestJS!"
B. 404 Not Found error
C. An empty response
D. A runtime error due to missing decorator

Solution

  1. Step 1: Analyze the route and method decorators

    The @Controller('hello') sets the base path to '/hello'. The @Get() decorator on greet() means this method handles GET requests to '/hello'.
  2. Step 2: Understand the method return value

    The greet() method returns the string 'Hello, NestJS!'. So, a GET request to '/hello' returns this string as the response.
  3. Final Answer:

    "Hello, NestJS!" -> Option A
  4. Quick Check:

    GET /hello returns method string = A [OK]
Hint: Match @Controller path with @Get method for output [OK]
Common Mistakes:
  • Assuming 404 because of missing route
  • Expecting JSON instead of string
  • Thinking decorators cause runtime errors here
4. Identify the error in the following NestJS service code:
@Injectable
export class UserService {
  getUser() {
    return { name: 'Alice' };
  }
}
medium
A. Return value must be a string, not an object
B. Missing parentheses in @Injectable decorator
C. Class name should be UserServices
D. Method getUser() should be async

Solution

  1. Step 1: Check the decorator syntax

    The @Injectable decorator requires parentheses even if no arguments are passed, so it should be @Injectable().
  2. 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.
  3. Final Answer:

    Missing parentheses in @Injectable decorator -> Option B
  4. 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

  1. 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.
  2. 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.
  3. 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.
  4. Final Answer:

    The code snippet with @Get(':id') and @Param('id') -> Option D
  5. 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 unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard