简体   繁体   中英

How to add a route prefix to specific modules using NestJS?

I want to add routing prefixes at the module level and/or have complex global routing prefix logic in general.

I know I can use the undocumented function NestApplication.setGlobalPrefix to set a single global prefix:

// main.ts
app.setGlobalPrefix(version);

However, I want to set prefixes at the module level in this case.

It appears I could achieve this by setting my desired prefix into the decorators at the controller level:

//controler.ts
@Get('/PREFIX/health')
async getHealth() {

  // TODO: implement
  return {};
}

But this seems fairly hacky and error-prone. Surely there is a better way?

Update 2021

NestJS now supports the original answer natively .

In addtion, NestJS v8 also adds more sophisticated routing when the primary function is versioning an API:

@Controller({
  path: 'cats',
  version: '1', // 👈
})
export class CatsController {
...

Original Answer

The most robust way to accomplish this in NestJS is to use the nest-router package to create a routing tree .

yarn add nest-router
# or npm i nest-router

Create a file next to main.ts called routes.ts like so:

import { Routes } from 'nest-router';
import { YourModule } from './your/your.module';

export const routes: Routes = [
  {
    path: '/v1',
    module: YourModule,
  },
];

Then, inside your app.module.ts file, add the router before any other modules are loaded:

@Module({
  imports: [
    RouterModule.forRoutes(routes),
    YourModule,
    DebugModule
  ],

})

Now when you navigate to YourModule controller, all of its routes will be prefixed with eg v1 in this case:

curl http://localhost:3000/v1/your/operation

Using this approach gives you the most flexibility as each module does not need to know how it will be prefixed; the application can decide at a higher level. Almost more advanced prefixes can be computed dynamic versus relying on a static string.

For me, adding a third party package just to achieve this would be a bit unnecessary, let alone the risk of it being outdated/unmaintained. You can add your custom route prefix in the Controller class instead.

  @Controller('custom/prefix')
  export const MyController {

     @Get('health')
     getHealth() {
       //this route would be: custom/prefix/health
       return {};
     }

     @Get('other')
     getOther() {
       //this route would be: custom/prefix/other
       return {};
     }
  }

Then just simply add this controller inside your Module

You can now use either the RouterModule configuration or you can exclude some paths from the global prefix configuration (or mix both):

RouterModule: https://docs.nestjs.com/recipes/router-module#router-module

Global prefix "exclude": https://docs.nestjs.com/faq/global-prefix#global-prefix

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM