Exploring a new nest new
project and examining the AppController
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get()
getHello(): string {
return this.appService.getHello();
}
}
(While using @Controller()
, it applies similarly to @Injectable()
, at least for the context of this discussion)
Now analyzing its compiled output, dist/app.controller.js
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AppController = void 0;
const common_1 = require("@nestjs/common");
const app_service_1 = require("./app.service");
let AppController = class AppController {
constructor(appService) {
this.appService = appService;
}
getHello() {
return this.appService.getHello();
}
};
__decorate([
(0, common_1.Get)(),
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", String)
], AppController.prototype, "getHello", null);
AppController = __decorate([
(0, common_1.Controller)(),
__metadata("design:paramtypes", [app_service_1.AppService])
], AppController);
exports.AppController = AppController;
//# sourceMappingURL=app.controller.js.map
A lot happening at the top of the file, defining methods like __deccorate
. Let's see it in action with the @Controller()
decorator
AppController = __decorate([
(0, common_1.Controller)(),
__metadata("design:paramtypes", [app_service_1.AppService])
], AppController);
The "design:paramtypes'
is crucial for Nest during application start as it specifies what to inject where. Nest identifies AppService
based on this information, then recursively reads the metadata of all related components until it can create the service, adding the provider to a metadata map and ensuring it doesn't duplicate services within the module context. It follows the metadata and injection tree to instantiate each service.
Note: The types for the @Get()
decorator and parameters are visible here. This data is utilized by Nest, particularly in pipes.
An important note is that the __decorate()
method and related metadata won't be included in Typescript output unless there is at least one decorator on the class, hence the use of @Inejctable()
. If the class lacks injections, technically @Injectable()
isn't necessary, but conventionally kept for consistency.