簡體   English   中英

如何在 Nestjs 中獲取所有路由(來自每個模塊上可用的所有模塊和控制器)?

[英]How can I get all the routes (from all the modules and controllers available on each module) in Nestjs?

使用 Nestjs,我想使用 http 動詞獲取所有可用路由(控制器方法)的列表,如下所示:

API:
      POST   /api/v1/user
      GET    /api/v1/user
      PUT    /api/v1/user

似乎需要訪問快速路由器,但我在 Nestjs 中找到了一種方法。 對於 express,有一些庫,例如“ express-list-routes ”或“ express-list-endpoints ”。

提前致謝!

我剛剛發現 Nestjs 應用程序有一個“getHttpServer()”方法,通過這個我能夠訪問“路由器堆棧”,這是解決方案:

// 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();

Nestjs 可用路線!

main.ts

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);
  const server = app.getHttpServer();
  const router = server._events.request._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();
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",
    ]
}

在 Nest 中,每個本機服務器都包裝在一個適配器中。 對於那些使用Fastify的人:

// main.ts

app
    .getHttpAdapter()
    .getInstance()
    .addHook('onRoute', opts => {
      console.log(opts.url)
    })

更多關於 fastify 鈎子的信息在這里

它完美地工作:

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

由於某種原因express-list-routes不適用於我的 NestJS。 但是有一個替代的解決方案:你可以使用@nestjs/swagger模塊來形成一個OpenAPI 文檔 它有一個paths字段,基本上列出了所有路線。 它使用 NestJS 裝飾器元數據而不是底層服務器模塊。

例子

import { DocumentBuilder, OpenAPIObject, SwaggerModule } from '@nestjs/swagger';
import type { INestApplication } from '@nestjs/common';

export function listNestJSApplicationRoutes(app: INestApplication): Array<{ method: string; path: string }> {
  const doc = SwaggerModule.createDocument(app, new DocumentBuilder().build());
  return Object.entries(doc.paths).flatMap(([path, pathContent]) =>
    Object.keys(pathContent).map((method) => ({ method, path })),
  );
}

此解決方案獨立於底層服務器模塊 - express 或 fastify。 它還自動考慮RouterModuleAPI 版本控制全局前綴 期望@nestjs/swagger將支持對 NestJS 內部 API 的任何更改以及任何修改 API 路由的新方法是有道理的,因為它由 Kamil Mysliwiec 本人維護。

如果您想知道@nestjs/swagger使用的 NestJS 的內部 API,您可以開始閱讀SwaggerModule.createDocument

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM