全局路由前缀
在为我们的应用设计路由接口的时候,如果需要有一个固定的前缀,比如需要说明一个指定的版本:
https://myHost.com.cn/app/private/v1
可以使用Nest提供的全局路由前缀方式设置,这里是官方地址:
const app = await NestFactory.create(AppModule);
app.setGlobalPrefix('app/private/v1');
控制器路由前缀
当然, 也可以在控制器Controller级别设置路由前缀:
// user.controller.ts
import { Controller, Get } from '@nestjs/common';
@Controller('users')
export class UsersController {
@Get(:id)
getUser(): string {
return 'This action returns user by id';
}
}
请求方式就是这样:
https://myHost.com.cn/app/private/v1/users/123
Module路由
对于Module级路由前缀的设置,是通过RouterModule类来设置的,这里是文档地址,示例如下:
@Module({
imports: [
RouterModule.register([
{
path: 'users', // 定义前缀
module: UsersModule // 应用在哪个moudule上
}
]),
UsersModule
],
controllers: [],
providers: [],
})
export class AppModule {
constructor() { }
}
通过官方文档介绍,通过这种方式还可以定义层次结构,每个Module可以有子Module,子Module将继承父Module的前缀。官方示例如下:
RouterModule.register([
{
path: 'admin',
module: AdminModule,
children: [
{
path: 'dashboard',
module: DashboardModule,
},
{
path: 'metrics',
module: MetricsModule,
},
],
},
]);
这样,请求方式就是:
***/admin/dashboard/***
***/admin/metrics/***
这样看来,当我们面对复杂业务场景、复杂项目,需要对路由进行设计和规划的时候,Nest提供的这种框架层面的设计,就保证了极大的自由度,去控制和组织好项目的代码结构。
一个小问题
RouterModule.register方法接收的参数是routerTree[],routerTree的定义如下:
export interface RouteTree {
path: string;
module?: Type<any>;
children?: Routes | Type<any>[];
}
module是可选的。我尝试用下面的方式设置:
@Module({
imports: [
RouterModule.register([
{
path: 'users', // 定义前缀
}
]),
UsersModule
],
controllers: [],
providers: [],
})
export class AppModule {
constructor() { }
}
发现没有效果,既不是全局定义,也不是所在Module级别的定义,目前还搞不懂,如果有大佬知道,希望不吝赐教!。。。
另一个设置Module前缀的方法(不推荐)
好奇心驱使下,查看了下Nest源码的创建Router部分:
首先查看了route-path-factory.js这个文件,是用来创建路由路径的工厂函数,在create方法里传入的metadata参数里,定义了modulePath、ctrlPath、methodPath、globalPrefix属性,这些应该就是用来拼接路由的。
继续向上查找,找到了routes-resolver.js文件,在这里找到了create方法的调用位置和metadata是如何组装的:
并进一步找到了modulePath的取值位置:
看到这里,modulePath是通过Reflect取的MODULE_PATH,MODULE_PATH的定义是这样的:
export declare const MODULE_PATH = "__module_path__";
所以,要定义Moudle级路由前缀modulePath,可以通过SetMetadata设置MODULE_PATH。示例如下:
import { Module } from '@nestjs/common';
import { SetMetadata } from '@nestjs/common';
import { MODULE_PATH } from '@nestjs/common/constants';
@SetMetadata(MODULE_PATH, 'manager')
@Module({
imports: [...],
providers: [...],
controllers: [...],
exports: [...],
})
export class ManagerModule { }
总结
以上内容官网均有涉及,浅浅记录,不值一提。如有错误,欢迎指正!!!
Nest中文官网和Nest英文官网内容不同步,英文官网更全更新一些,RouterModule的使用说明也是在英文官网发现的, 在中文官网没有找到。