Skip to content

Commit 6ac96ab

Browse files
committed
迁移指南
1 parent a5ac970 commit 6ac96ab

File tree

1 file changed

+94
-78
lines changed

1 file changed

+94
-78
lines changed

7/migrationguide.md

Lines changed: 94 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,123 +1,139 @@
1-
## 迁移指南
1+
### 迁移指南
22

3+
本文提供了一套从 v6 迁移到最新 v7 版本的指导。
34

4-
本文提供了一套从 `v5` 迁移到最新 `v6` 版本的**指导原则**。尽管我们试图减少一些重大变化,但必须在几个地方修改 `API` 以简化其使用。
5+
#### 自定义路由参数装饰器
56

6-
### 中间件
7-
8-
基于[此主题](https://github.com/nestjs/nest/issues/1378),中间件 `API` 已经更改,以便来自不同 `Node` 库的人员更直接使用,并减少先前 `API` 产生的混淆。
7+
已经对所有类型的应用程序的 [自定义装饰器](/customdecorators) API 做了统一,现在无论您创建的是 `GraphQL` 应用程序还是 `RestAPI` 应用程序,`执行上下文(ExecutionContext)`[阅读更多](/fundamentals/execution-context))都会作为第二个参数传递到 `createParamDecorator()` 函数
98

109
```typescript
1110
// Before
12-
@Injectable()
13-
export class LoggerMiddleware implements NestMiddleware {
14-
resolve(...args: any[]): MiddlewareFunction {
15-
return (req: Request, res: Response, next: Function) => {
16-
console.log('Request...');
17-
next();
18-
};
19-
}
20-
}
11+
import { createParamDecorator } from '@nestjs/common';
12+
13+
export const User = createParamDecorator((data, req) => {
14+
return req.user;
15+
});
2116

2217
// After
23-
@Injectable()
24-
export class LoggerMiddleware implements NestMiddleware {
25-
use(req: Request, res: Response, next: Function) {
26-
console.log('Request...');
27-
next();
28-
}
29-
}
30-
```
18+
import { createParamDecorator, ExecutionContext } from '@nestjs/common';
3119

32-
因此,该 `with()` 方法 `MiddlewareConsumer` 将不再起作用(完全无用)。如果要将选项传递给中间件类,请使用[自定义提供程序](/6/customdecorators)[在此处](https://github.com/nestjs/nest/issues/1378)查看更多示例。
20+
export const User = createParamDecorator(
21+
(data: unknown, ctx: ExecutionContext) => {
22+
const request = ctx.switchToHttp().getRequest();
23+
return request.user;
24+
},
25+
);
26+
```
3327

34-
### 拦截器
28+
#### 微服务
3529

36-
拦截器 `API` 也已简化。此外,由于社区报告[此问题](https://github.com/nestjs/nest/issues/1016),因此需要进行更改
30+
为了避免代码重复,`MicroserviceOptions` 接口(Interface)已从 `@nestjs/common` 包中删除。因此,现在在创建微服务(通过 `createMicroservice()``connectMicroservice()` 方法)时,应该传递泛型类型参数以自动完成代码获取
3731

3832
```typescript
3933
// Before
40-
@Injectable()
41-
export class TransformInterceptor implements NestInterceptor {
42-
intercept(
43-
context: ExecutionContext,
44-
call$: Observable<T>,
45-
): Observable<Response<T>> {
46-
return call$.pipe(map(data => ({ data })));
47-
}
48-
}
34+
const app = await NestFactory.createMicroservice(AppModule);
4935

5036
// After
51-
@Injectable()
52-
export class TransformInterceptor implements NestInterceptor {
53-
intercept(
54-
context: ExecutionContext,
55-
next: CallHandler,
56-
): Observable<Response<T>> {
57-
return next
58-
.handle()
59-
.pipe(map(data => ({ data })));
60-
}
61-
}
37+
const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule);
6238
```
6339

64-
!> 该 `CallHandler` 接口需要从 `@nestjs/common ` 包导入
40+
> 提示:`MicroserviceOptions` 接口(Interface)是从 `@nestjs/microservices` 包导出的
6541
66-
请注意,你的拦截器现在将以正确的顺序运行 - 它们将遵循一个简单的请求来处理管道,一旦请求想要命中一个终端处理程序,就从全局执行到具体执行,然后(在响应管道中),它们将是从特定的到全局的(如果你在其中附加一些异步/映射逻辑)执行。
42+
#### GraphQL
6743

44+
在NestJS第6版的主要版本中,我们引入了 ***代码优先*** 的方法,作为 `type-graphql` 包和 `@nestjs/graphql` 模块之间的兼容层。最终,由于缺乏灵活性,我们的团队决定从头开始重新实现所有功能。为了避免大量断层更改,公开API是向后兼容的,可能类似于 `type-graphql`
6845

69-
### 平台
46+
迁移现有的应用程序,只需将所有从 `type-graphql` 导入的改为从 `@nestjs/graphql` 导入即可。
7047

71-
到目前为止,即使您没有使用 `HTTP` 服务器,也必须在内部安装 `express` 库(作为 `@nestjs/core` 软件包的依赖项)。自从新的主要版本发布以来,`Nest` 将不再提供这些软件包。每个平台已经提取到单个包中,分别为 `@nestjs/platform-express``@nestjs/platform-fastify``@nestjs/platform-ws`,和 `@nestjs/platform-socket.io`。假设您的应用程序同时使用 `express``socket.io`,则需安装相应的平台:
48+
#### HTTP exceptions body
7249

73-
```
74-
$ npm i @nestjs/platform-express @nestjs/platform-socket.io
75-
```
50+
以前,为`HttpException` 类以及从 `HttpException` 派生的其他类生成的响应体不一致(例如,`BadRequestException``NotFoundException`)。在最新的主要版本中,这些异常响应将采用相同的结构。
7651

77-
现在,每个现有的适配器(例如 `FastifyAdapter`)都是从专用平台包提供的。
7852

53+
```typescript
54+
/*
55+
* Sample outputs for "throw new ForbiddenException('Forbidden resource')"
56+
*/
7957

80-
- FastifyAdapter - @nestjs/platform-fastify
81-
- ExpressAdapter - @nestjs/platform-express
82-
- WsAdapter - @nestjs/platform-ws
83-
- IoAdapter - @nestjs/platform-socket.io
84-
85-
此外,`FileInterceptor`(和其他 `multer` 相关的拦截器)现在从 `@nestjs/platform-express`(因为 `multer` 库不兼容 `fastify`)导出 。
58+
// Before
59+
{
60+
"statusCode": 403,
61+
"message": "Forbidden resource"
62+
}
8663

87-
### 元数据相关
64+
// After
65+
{
66+
"statusCode": 403,
67+
"message": "Forbidden resource",
68+
"error": "Forbidden"
69+
}
70+
```
8871

89-
`@ReflectMetadata()` 装饰已被弃用,并将在下一主要版本中删除(现在它只会显示一个警告)。请改用 `@SetMetadata()` 装饰器。
72+
#### Validation errors schema
9073

91-
### GraphQL
74+
在过去的版本中,`ValidationPipe` 抛出一个由 `class-validator` 包返回的 `ValidationError` 对象数组。现在,`ValidationPipe` 将错误映射到表示错误消息的纯字符串列表。
9275

93-
订阅机制已更改。检查[此章](/6/subscriptions)的说明。此外,`@nestjs/graphql` 软件包严重依赖 `@ReflectMetadata()`(已被弃用),因此也需要更新软件包本身。
76+
```typescript
77+
// Before
78+
{
79+
"statusCode": 400,
80+
"error": "Bad Request",
81+
"message": [
82+
{
83+
"target": {},
84+
"property": "email",
85+
"children": [],
86+
"constraints": {
87+
"isEmail": "email must be an email"
88+
}
89+
}
90+
]
91+
}
9492

95-
### Express实例
93+
// After
94+
{
95+
"statusCode": 400,
96+
"message": ["email must be an email"],
97+
"error": "Bad Request"
98+
}
99+
```
96100

97-
我们不再支持将 `express` 实例作为方法的第二个参数传递 `NestFactory.create()` 。为了获取底层 `HTTP` 适配器,请使用[此处](/6/faq?id=http-适配器)描述的技术。此外,您可以传递 `ExpressAdapter`(只需将您的 `express` 实例作为构造函数参数传递 `new ExpressAdapter(express)`)。
101+
如果你喜欢以前的方式,你可以通过设置 `exceptionFactory` 函数来还原:
98102

99103
```typescript
104+
new ValidationPipe({
105+
exceptionFactory: errors => new BadRequestException(errors),
106+
});
107+
```
100108

101-
// Before (no longer supported)
102-
const server = express();
103-
const app = await NestFactory.create(ApplicationModule, server);
109+
#### 类型隐式转换 (`ValidationPipe`)
104110

105-
// After (potential solution)
106-
const server = express();
107-
const app = await NestFactory.create(
108-
ApplicationModule,
109-
new ExpressAdapter(server),
110-
);
111+
如果启用了自动转换选项(`transform: true`),那么`ValidationPipe` 现在将会执行基于元类型的转换。在下面的示例中,`findOne` 方法接受一个表示提取 `id` 路径参数的参数:
111112

113+
```typescript
114+
@Get(':id')
115+
findOne(@Param('id') id: number) {
116+
console.log(typeof id === 'number'); // true
117+
return 'This action returns a user';
118+
}
112119
```
113120

114-
### 弃用
121+
默认情况下,每个路径参数和查询参数都是以 `string` 类型在网络传输。在上面的示例中,我们将 `id` 的类型指定为 `number`类型,因此,`ValidationPipe` 会自动尝试将标识符 `id` 的值从 `sting` 类型转为 `number` 类型。
122+
123+
#### 微服务通道(双向通信)
124+
125+
为了启用 `请求-响应` 消息类型, `Nest` 创建了两个逻辑通道 - 一个是负责数据传输,另一个是负责等待传入的响应。对于一些底层传输,例如 `NATS` 这种 `双通道` 是支持的,开箱即用。对于其他的,`Nest` 通过手动创建单独的通道来进行支持。
126+
127+
假设我们有一个消息处理器 `@MessagePattern('getUsers')`。在过去, `Nest` 根据这种模式会创建两个通道:`getUsers_ack` (用于请求)和`getUsers_res` (用于响应)。现在,`Nest 7`中这种命名方案将会更改。将会更改为 `getUsers`(用于请求)和 `getUsers.reply`(用于响应)。同样,对于 `MQTT` 的传输策略,响应通过将会是 `getUsers/reply`(以避免与主题通配符冲突)。
128+
129+
#### 弃用
130+
131+
所有的弃用的(从Nest version 5到version 6)最终都被删除了(例如,弃用了的`@reflectmetada` decorator)。
115132

116-
最终删除了所有弃用(从 `4``5` 版本)。
133+
#### Node.js
117134

118-
### TypeScript
135+
这个版本不再对Node v8的支持。我们强烈建议使用最新的LTS版本。
119136

120-
`Nest 6` 支持 `TypeScript(3.0.0)`的最新主要版本。
121137

122138
### 译者署名
123139

0 commit comments

Comments
 (0)