11

I have this microservice written with NestJs:

async function bootstrap() {
  const port = parseInt(process.env.PORT || '5000', 10);

  const app = await NestFactory.createMicroservice(ApplicationModule, {
    transport: Transport.TCP,
    options: { host: '0.0.0.0', port }
  });
  app.listen(() => console.log(`Microservice is listening on port ${port}`));
}
bootstrap();

But now I need to implement an endpoint /metrics for Prometheus. So the question is how do I do this with NestJs microservice

From this issue I get the impression that it is not possible. Is this true and if so, is there a workaround I can use?

I tried to apply middleware as follows

Module({
  imports: [],
  controllers: [AppController],
  providers: [AppService, DBService],
})
export class ApplicationModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(MetricsMiddleware)
      .forRoutes('/metrics') // Also tried '*'
  }
}

But when I do curl http://localhost:5000/metrics nothing happens, the middleware is not called

@Injectable()
export class MetricsMiddleware implements NestMiddleware {
    constructor() {}

    use(req, res, next) {
        console.log('yes');
        next();
    }
}

Update: This issue will also not help :(

Kim Kern
  • 54,283
  • 17
  • 197
  • 195
Jeanluca Scaljeri
  • 26,343
  • 56
  • 205
  • 333

1 Answers1

23

If you want your application to support both http requests and a microservice, you can create a hybrid application.

// Create your regular nest application.
const app = await NestFactory.create(ApplicationModule);

// Then combine it with your microservice
const microservice = app.connectMicroservice({
  transport: Transport.TCP,
  options: { host: '0.0.0.0', port: 5000 }
});

await app.startAllMicroservices();
await app.listen(3001);
Kim Kern
  • 54,283
  • 17
  • 197
  • 195
  • What if I want all my microservices to be able to support http requests, but also be able to communicate with each other. Is this possible? – Shirohige Nov 23 '19 at 09:35
  • @Shirohige Have a look at this thread: https://stackoverflow.com/a/53996635/4694994 – Kim Kern Nov 23 '19 at 16:11
  • Wait, this already is a hybrid application... What do you mean? They can all communicate with each other either via the "microservice protocol" or http. – Kim Kern Nov 23 '19 at 16:14
  • So I'm trying to expose endpoints to my web application from multiple microservices. For example, if I do a GET request on /users, it will hit an endpoint from the Users service, and if I do a GET requests on /notifications, it will hit an endpoint from the Notifications service. With the hybrid application, it seems to me that only the 'main' app that connects all microservices is able to expose endpoints and connect to the other microservices, or should all other microservices also be instantiated with the hybrid approach? – Shirohige Nov 24 '19 at 13:48
  • @Shirohige But are you using any other transport protocol besides your http requests? If not, simply create all your microservices as regular applications. Only if you want to use an additional transport protocol besides http you need to create a hybrid application. – Kim Kern Nov 24 '19 at 14:05
  • It's rather hard to understand your requirements in the limited space of a comment. Maybe consider opening a new question. – Kim Kern Nov 24 '19 at 14:08
  • I'm new to NestJS and microservices overall. I will go with your suggestion and just create multiple regular applications, thanks very much! – Shirohige Nov 24 '19 at 14:16
  • 2
    `startAllMicroservicesAsync()` is now **deprecated**. you can use the alternative similarly: `await app.startAllMicroservices();` – Maor Barazani Feb 15 '22 at 11:48