the error I have is similar to this: Dependencies not being injected on NestJS with Serverless and AWS, but the solution they give is already configured in my project, when I run the normal app, with npm run start:.. it works correctly, but when running it with serverless, I have the failure of the undefined in the services in the constructor, here I leave a summary of the configuration and code:
libsutilsutils.module.ts
import { Module } from '@nestjs/common';
import { UtilsService } from './utils.service';
import { UtilsController } from './utils.controller';
@Module({
providers: [UtilsService],
exports: [UtilsService],
controllers: [UtilsController]
})
export class UtilsModule {}
libsutilsutils.service.ts
import {
Injectable,
} from '@nestjs/common';
@Injectable()
export class UtilsService {
getHello(): string {
return 'Hello World!';
}
}
mcrseguros-estadosrcseguros-estado.module.ts
import { Module } from '@nestjs/common';
import { SegurosEstadoService } from './seguros-estado.service';
import { SegurosEstadoController } from './seguros-estado.controller';
import { TypeOrmModule } from '@nestjs/typeorm';
import { CitiesDane } from '../../../libs/entities/CitiesDane';
import { InsuranceConfigurations } from '../../../libs/entities/InsuranceConfigurations';
import { Fasecolda } from '../../../libs/entities/Fasecolda';
import { UtilsModule } from '../../../libs/utils/utils.module';
import { LoggerModule } from '../../../libs/logger/logger.module';
import { ErrorsService } from '../../../libs/errors/errors.service';
import * as dotenv from 'dotenv';
dotenv.config();
@Module({
imports: [
TypeOrmModule.forRoot({
type: 'mysql', // Tipo de base de datos, por ejemplo, 'mysql', 'mariadb', 'postgres', etc.
host: process.env.DB_HOST, // Dirección del host
port: parseInt(process.env.DB_PORT, 10), // Puerto de la base de datos
username: process.env.DB_USER, // Usuario de la base de datos
password: process.env.DB_PW, // Contraseña del usuario de la base de datos
database: process.env.DB_NAME, // Nombre de la base de datos
entities: [__dirname + '/../../../libs/entities/**/*{.ts,.js}'], // Ruta a las entidades
synchronize: process.env.DB_SYNC === "true", // Solo en desarrollo; sincroniza la estructura de la base de datos con las entidades
autoLoadEntities: true,
logging: ['query', 'error'],
}),
TypeOrmModule.forFeature([CitiesDane]),
TypeOrmModule.forFeature([InsuranceConfigurations]),
TypeOrmModule.forFeature([Fasecolda]),
UtilsModule,
LoggerModule,
ErrorsService,
],
providers: [SegurosEstadoService],
controllers: [SegurosEstadoController],
})
export class SegurosEstadoModule {}
mcrseguros-estadosrcseguros-estado.controller.ts
import { Body, Controller, Get, Inject, Post } from '@nestjs/common';
import { LoggerService } from '../../../libs/logger/logger.service';
import { UtilsService } from '../../../libs/utils/utils.service';
import * as path from 'path';
import { SegurosEstadoService } from './seguros-estado.service';
const pdf2base64 = require('pdf-to-base64');
const fse = require('fs-extra');
@Controller("seguros-estado")
export class SegurosEstadoController {
constructor(
private utilService: UtilsService,
private estadoService: SegurosEstadoService,
private loggerService: LoggerService,
) {
console.log("🚀 ~ SegurosEstadoController ~ utilService:", utilService) // undefined
console.log("🚀 ~ SegurosEstadoController ~ loggerService:", loggerService) // undefined
console.log("🚀 ~ SegurosEstadoController ~ estadoService:", estadoService) // undefined
}
@Get('test-r')
async testR() {
console.log(this.utilService.getHello()); // cannon read prop getHello to undefined
return { succesfully: true}
}
tsconfig.json
{
"compilerOptions": {
"module": "commonjs",
"declaration": true,
"removeComments": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
//"allowSyntheticDefaultImports": true,
"target": "ES2021",
"sourceMap": true,
"outDir": "./dist",
"baseUrl": "./",
"incremental": true,
"skipLibCheck": true,
"strictNullChecks": false,
"noImplicitAny": false,
"strictBindCallApply": false,
"forceConsistentCasingInFileNames": false,
"noFallthroughCasesInSwitch": false,
"paths": {
"libs/*": ["libs/*"]
}
},
"include": ["src/**/*.ts", "mcr/**/*.ts", "libs/**/*.ts"],
}
serverless.yml
service: nestjs-microservices
frameworkVersion: '4'
provider:
name: aws
runtime: nodejs18.x
region: us-east-1
memorySize: 128
timeout: 240
environment:
NODE_ENV: production
REDIS_HOST: <redis-host>
REDIS_PORT: <redis-port>
functions:
segurosEstado:
handler: mcr/seguros-estado/src/main.handler
events:
- http:
path: seguros-estado/{proxy+}
method: ANY
cors: true
allianz:
handler: mcr/allianz/src/main.handler
events:
- http:
path: allianz/{proxy+}
method: ANY
cors: true
plugins:
- serverless-offline
custom:
serverless-offline:
httpPort: 3001
debug: true
mcrseguros-estadosrcmain.ts
import { NestFactory } from '@nestjs/core';
import serverlessExpress from '@vendia/serverless-express';
import { Handler } from 'aws-lambda';
import { SegurosEstadoModule } from './seguros-estado.module';
let cachedHandler: Handler;
export const handler: Handler = async (event, context) => {
if (!cachedHandler) {
const app = await NestFactory.create(SegurosEstadoModule);
await app.init();
// Obtén la instancia de Express para serverless-express
const expressApp = app.getHttpAdapter().getInstance();
// Configura el adaptador serverless-express
cachedHandler = serverlessExpress({ app: expressApp });
}
return cachedHandler(event, context);
};
// Si no estás en un entorno de Lambda, puedes correrlo como un servidor HTTP local
if (process.env.IS_LOCAL === 'true') {
const bootstrap = async () => {
const app = await NestFactory.create(SegurosEstadoModule);
const port = process.env.SEGUROS_ESTADO_PORT || 3001; // Usar el puerto desde el .env
await app.listen(port);
console.log(`Microservicio Seguros Estado corriendo en http://localhost:${port}`);
};
bootstrap();
}
Now when I run the app with "ts-node-dev mcr/secure-state/src/main.ts" it works correctly, but with "npx serverless offline":
Server ready: http://localhost:3001 �
ANY /dev/seguros-estado/seguros-estado/test-r (λ: segurosEstado)
[Nest] 6640 - 08/01/2025, 2:04:25 p. m. LOG [NestFactory] Starting Nest application...
[Nest] 6640 - 08/01/2025, 2:04:25 p. m. LOG [NestFactory] Starting Nest application... +7ms
[Nest] 6640 - 08/01/2025, 2:04:25 p. m. LOG [InstanceLoader] TypeOrmModule dependencies initialized +503ms
[Nest] 6640 - 08/01/2025, 2:04:25 p. m. LOG [InstanceLoader] LoggerModule dependencies initialized +0ms
[Nest] 6640 - 08/01/2025, 2:04:25 p. m. LOG [InstanceLoader] ErrorsService dependencies initialized +0ms
[Nest] 6640 - 08/01/2025, 2:04:25 p. m. LOG [InstanceLoader] TypeOrmModule dependencies initialized +1ms
[Nest] 6640 - 08/01/2025, 2:04:25 p. m. LOG [InstanceLoader] LoggerModule dependencies initialized +0ms
[Nest] 6640 - 08/01/2025, 2:04:25 p. m. LOG [InstanceLoader] ErrorsService dependencies initialized +0ms
[Nest] 6640 - 08/01/2025, 2:04:25 p. m. LOG [InstanceLoader] UtilsModule dependencies initialized +0ms
[Nest] 6640 - 08/01/2025, 2:04:25 p. m. LOG [InstanceLoader] UtilsModule dependencies initialized +0ms
query: SELECT VERSION() AS `version`
query: SELECT VERSION() AS `version`
[Nest] 6640 - 08/01/2025, 2:04:27 p. m. LOG [InstanceLoader] TypeOrmCoreModule dependencies initialized +1656ms
[Nest] 6640 - 08/01/2025, 2:04:27 p. m. LOG [InstanceLoader] TypeOrmModule dependencies initialized +1ms
[Nest] 6640 - 08/01/2025, 2:04:27 p. m. LOG [InstanceLoader] TypeOrmModule dependencies initialized +0ms
[Nest] 6640 - 08/01/2025, 2:04:27 p. m. LOG [InstanceLoader] TypeOrmModule dependencies initialized +0ms
� ~ SegurosEstadoController ~ utilService: undefined
� ~ SegurosEstadoController ~ loggerService: undefined
� ~ SegurosEstadoController ~ estadoService: undefined
[Nest] 6640 - 08/01/2025, 2:04:27 p. m. LOG [InstanceLoader] SegurosEstadoModule dependencies initialized +1ms
[Nest] 6640 - 08/01/2025, 2:04:27 p. m. LOG [RoutesResolver] SegurosEstadoController {/seguros-estado}: +15ms
[Nest] 6640 - 08/01/2025, 2:04:27 p. m. LOG [RouterExplorer] Mapped {/seguros-estado/test-r, GET} route +9ms
[Nest] 6640 - 08/01/2025, 2:04:27 p. m. LOG [RouterExplorer] Mapped {/seguros-estado/poliza-r, POST} route +1ms
[Nest] 6640 - 08/01/2025, 2:04:27 p. m. LOG [RouterExplorer] Mapped {/seguros-estado/print-r, POST} route +1ms
[Nest] 6640 - 08/01/2025, 2:04:27 p. m. LOG [RoutesResolver] UtilsController {/utils}: +1ms
[Nest] 6640 - 08/01/2025, 2:04:27 p. m. LOG [NestApplication] Nest application successfully started +5ms
Microservicio Seguros Estado corriendo en http://localhost:3001
[Nest] 6640 - 08/01/2025, 2:04:27 p. m. ERROR [ExceptionsHandler] Cannot read properties of undefined (reading 'getHello')
(λ: segurosEstado) RequestId: 04af350e-244b-4dbf-9113-9c4c9476cda3 Duration: 17758.24 ms Billed Duration: 17759 ms
2
Answers
Finally the solution was to add the decorators @Inject(--service_name--) in the injections in the constructor:
You can try adding
"esModuleInterop": true
to your tsconfig.json file and load your handlers in yourserverless.yml
configuration file fromdist
folder.