初窥 NestJs
NestJs 是一个 NodeJs 的服务端框架,同 Spring 与 Java 的关系
一、安装、使用
1. 安装脚手架 nestjs-cli
1 |
|
2. 创建 Starter
通过命令 nest new project
可以创建一个 Starter 项目:https://github.com/nestjs/typescript-starter.git
然后可以自行修改一些配置,创建属于自己的 Starter,例如将 Controller、Service、Module 分目录存放等等。本文中按照以上目录来进行分类。
3. 路由 Controller
3.1. 创建路由
使用 @Controller()
装饰器定义一个基本的控制器,可以设置参数代表路由路径前缀,默认是 /
,例如路由路径前缀:/user
则可以使用装饰器:@Controller('user')
1 |
|
可以通过 CLI
创建控制器:nest g controller name saveDir
,简写:nest g co name saveDir
- 在
src/controller/name
路径下创建name.controller.ts
- 在
src/controller/name
路径下创建name.controller.spec.ts
,若不需要该测试文件,则可以加入--no-spec
参数来取消。
3.2. 路由匹配规则
按照 Controller 中定义的顺序进行匹配,找到第一个匹配上的路由规则,并交由该函数处理,本质上是将这些路由规则对应的函数绑定到 Controller 对应的原型链上,可在 dist/*.controller.js
文件中查看到
1 |
|
在参数相同的情况下,会将 test
路由交给 test1
函数来处理。
3.2.1. 路由通配符
路由支持使用模式匹配,支持的匹配规则有:
*
:匹配任何组合字符,包括空字符,例如:a*c
,将会匹配路由:ac
、axxxc
?
:前面一个字符的0-1
次拓展,例如:a?c
,将会匹配路由:c
、ac
+
:前面一个字符的1-n
次拓展,例如:a+c
,将会匹配路由:ac
、aac
、aaac
()
:用处就是把括号内的视为一个字符与上面的合用,例如:ac(ac)?
:将会匹配路由:ac
、acac
3.2.2. Http 方法装饰器
Nest 为所有标准的 HTTP 方法提供了相应的装饰器:
@Get()、@Post()、@Put()、@Delete()
:Restful 风格@All()
:用来处理所有 HTTP 请求方法的处理程序@Patch()
@Options()
@Head()
3.2.3. 子域路由
@Controller
装饰器可以接受一个 host
选项,以要求传入请求的 HTTP
主机匹配某个特定值。默认采用 Express
适配器,因为 Fastify
不支持嵌套路由;
1 |
|
3.3. Request
3.3.1. 请求参数装饰器
通过装饰器 @Query
、@Params
、@Body
来获取三种传参方式
@Query
获取?name1=value1&name2=value2
这种类型的传参1
2
3
4@Get('testRequestQuery')
testRequestQuery(@Query('version') version: string): string {
return `${version !== undefined ? version : '未传 version'}`;
}@Params
获取/search/:id
这种类型的传参1
2
3
4
5
6
7
8
9
10
11
12@Get('testRequestParams/:username/:id')
testRequestParams(
// 推荐一个一个接收,还可以定义参数类型
@Param('username') username: string,
@Param('id') id: number,
): string
// 可以通过一个变量接收所有路径参数 @Param() params
// 然后这样获取参数
// console.log(params.username, params.id);
// return `${JSON.stringify(params)}`;
return `${username}, ${id}`;
}@Body
获取 POST 请求体的传参,一般推荐定义 DTO,然后自动注入1
2
3
4
5
6
7
8
9
10@Post('testRequestBody')
testRequestBody(
@Body() loginUser: LoginUserDto,
@Req() req: Request,
): string {
// 可以接收 application/x-www-form-urlencoded 与
// application/json 类型参数
console.log(req.headers['content-length']);
return `${JSON.stringify(loginUser)}`;
}
application/x-www-form-urlencoded
与 application/json
的区别,当传输数据参数涉及中文字符较少时,采取第一种格式请求体更短,传输数据参数中文字符较多时,采用第二种格式请求体更短。
因为第一种会将中文进行 urlencoded
编码,第二种有额外的 json
格式的开销。
3.4. Headers
3.4.1 状态码 HttpCode
默认情况下,http 请求正常返回状态码都是 200
(除了 POST 请求是 201
)可以通过 @HttpCode(code)
装饰器来修改返回状态码。
也可以通过 response
对象自行修改返回码,详见 3.5
3.4.2. 自定义响应头
所设置字符应该符合 Header 规范,否则会报错。
通过 @Header('key', 'value')
装饰器来向响应体中注入自定义 Header,其通过调用 res.header(key, value)
来实现。
3.4.3. 重定向 Redirect
通过 @Redirect('url', 'statusCode')
装饰器来重定向请求,statusCode
默认为 302
,这里可以分为静态重定向与动态重定向:
1 |
|
动态重定向,按照一些请求参数,动态的进行重定向。
1 |
|
3.5 Response
如果通过 `Res()` 或 `Response()` 装饰器拿到了 `response` 对象,则需要自行处理响应,否则服务会一直处于挂起状态!!!
Res()
是 Response()
的别名,个人认为作用是:当使用 TypeScript 时,需要标明变量类型,而 response
变量的类型是 Response
与装饰器 Response()
名称冲突,故而起了别名;也或许是仅仅为了简写;
1 |
|
4. Providers
Providers 是 Nest 的一个基本概念。许多基本的 Nest 类都可能被视为 provider:service、repository、factory、helper 等等。都可以通过 constructor 注入依赖关系。Provider 只是一个用 @Injectable() 装饰器注释的类。
4.1. 创建 Service
使用装饰器 @Injectable()
来标注一个类作为 Provider,让其由 Controller 使用,
可以通过 CLI
工具来创建 nest g service name saveDir
,该命令会自动创建:
name.service.ts
:service 文件name.service.spec.ts
:测试文件,通过--no-spec
参数取消生成该文件
1 |
|
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!