Reputation: 750
Using Nestjs I'd like to get a list of all the available routes (controller methods) with http verbs, like this:
API:
POST /api/v1/user
GET /api/v1/user
PUT /api/v1/user
It seems that access to express router is required, but I haven found a way to do this in Nestjs. For express there are some libraries like "express-list-routes" or "express-list-endpoints".
Thanks in advance!
Upvotes: 27
Views: 36985
Reputation: 1065
main.ts
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(3000);
const server = app.getHttpAdapter().getInstance();
const router = server.router;
const availableRoutes: [] = router.stack
.map(layer => {
if (layer.route) {
return {
route: {
path: layer.route?.path,
method: layer.route?.stack[0].method,
},
};
}
})
.filter(item => item !== undefined);
console.log(availableRoutes);
}
bootstrap();
Upvotes: 38
Reputation: 11
In NestJS 10, you can do it like this:
constructor(
private readonly _discoveryService: DiscoveryService,
private readonly _reflector: Reflector){}
private async getAllEndpoints(): Promise<void> {
const getRoutes = [];
const controllers = this._discoveryService.getControllers();
controllers.forEach(wrappper => {
const { instance } = wrappper;
if (instance) {
const controllerPath = this._reflector.get<string>(PATH_METADATA, instance.constructor);
const methods = Object.getOwnPropertyNames(Object.getPrototypeOf(instance));
methods.forEach(methodName => {
const methodHandler = instance[methodName];
const methodPath = this._reflector.get<string>(PATH_METADATA, methodHandler);
const requestMethod = this._reflector.get<RequestMethod>(METHOD_METADATA, methodHandler);
const baseUri = `${controllerPath} `;
const method = RequestMethod[requestMethod];
if (method) {
getRoutes.push({
path: methodPath == '/' ? baseUri : `${baseUri}/${methodPath}`,
method: method,
});
}
});
}
});
}
Output
[
{ path: 'auth/login', method: 'POST' },
{ path: 'auth/password/change', method: 'PATCH' }
]
Upvotes: 1
Reputation: 67
It works perfectly:
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import * as expressListRoutes from 'express-list-routes';
async function getApp() {
const app = await NestFactory.create(AppModule);
await app.listen(3000);
expressListRoutes(app.getHttpServer()._events.request._router);
return app;
}
getApp();
Output:
[Nest] 11619 - 10/03/2022 19:53:56 LOG [NestApplication] Nest application successfully started +3ms
GET /ui
GET /ui-json
GET /
GET /api/v1/auth
Upvotes: -1
Reputation: 111
import { Controller, Get, Request } from "@nestjs/common";
import { Request as ExpressRequest, Router } from "express";
...
@Get()
root(@Request() req: ExpressRequest) {
const router = req.app._router as Router;
return {
routes: router.stack
.map(layer => {
if(layer.route) {
const path = layer.route?.path;
const method = layer.route?.stack[0].method;
return `${method.toUpperCase()} ${path}`
}
})
.filter(item => item !== undefined)
}
}
...
{
"routes": [
"GET /",
"GET /users",
"POST /users",
"GET /users/:id",
"PUT /users/:id",
"DELETE /users/:id",
]
}
Upvotes: 11
Reputation: 153
In Nest every native server is wrapped in an adapter. For those, who use Fastify
:
// main.ts
app
.getHttpAdapter()
.getInstance()
.addHook('onRoute', opts => {
console.log(opts.url)
})
More about fastify hooks here.
Upvotes: 8
Reputation: 750
I just found that Nestjs app has a "getHttpServer()" method, with this I was able to access the "router stack", here's the solution:
// main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import * as expressListRoutes from 'express-list-routes';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.enableCors();
await app.listen(3000);
const server = app.getHttpServer();
const router = server._events.request._router;
console.log(expressListRoutes({}, 'API:', router));
}
bootstrap();
Upvotes: 12