Skip to content

Commit 8dcd338

Browse files
docs(): update config and migration guide
1 parent 66b1cd1 commit 8dcd338

File tree

3 files changed

+36
-336
lines changed

3 files changed

+36
-336
lines changed

content/fundamentals/lazy-loading-modules.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ const lazyService = moduleRef.get(LazyService);
9797
9898
#### Lazy-loading controllers, gateways, and resolvers
9999
100-
Since controllers (or resolvers in **GraphQL** applications) in Nest represent sets of routes/paths/topics (or queries/mutations), you cannot lazy load them using the `LazyModuleLoader` class.
100+
Since controllers (or resolvers in GraphQL applications) in Nest represent sets of routes/paths/topics (or queries/mutations), you **cannot lazy load them** using the `LazyModuleLoader` class.
101101
102102
> error **Warning** Controllers, [resolvers](/graphql/resolvers), and [gateways](/websockets/gateways) registered inside lazy-loaded modules will not behave as expected. Similarly, you cannot register middleware functions (by implementing the `MiddlewareConsumer` interface) on-demand.
103103

content/migration.md

Lines changed: 22 additions & 330 deletions
Original file line numberDiff line numberDiff line change
@@ -1,346 +1,38 @@
11
### Migration guide
22

3-
This article provides a set of guidelines for migrating from Nest version 6 to version 7.
3+
This article provides a set of guidelines for migrating from Nest version 7 to version 8.
4+
To learn more about the new features we've added in the v8, check out this [link](https://github.com/nestjs/nest/pull/6349).
45

5-
#### Custom route decorators
6+
#### HTTP module
67

7-
The [Custom decorators](/custom-decorators) API has been unified for all types of applications. Now, whether you're creating a GraphQL application or a REST API, the factory passed into the `createParamDecorator()` function will take the `ExecutionContext` (read more [here](/fundamentals/execution-context)) object as a second argument.
8+
The `HttpModule` exported from the `@nestjs/common` package has been deprecated and will be removed in the next major release.
9+
Instead, please use the `@nestjs/axios` package (otherwise, there are no API differences).
810

9-
```typescript
10-
@@filename()
11-
// Before
12-
import { createParamDecorator } from '@nestjs/common';
11+
#### gRPC strategy
1312

14-
export const User = createParamDecorator((data, req) => {
15-
return req.user;
16-
});
13+
The original Node gRPC library (`grpc`) has been deprecated and will no longer receive feature updates.
14+
With Nest v8, you should use the `@grpc/grpc-js` library instead.
1715

18-
// After
19-
import { createParamDecorator, ExecutionContext } from '@nestjs/common';
16+
#### NATS strategy
2017

21-
export const User = createParamDecorator(
22-
(data: unknown, ctx: ExecutionContext) => {
23-
const request = ctx.switchToHttp().getRequest();
24-
return request.user;
25-
},
26-
);
27-
@@switch
28-
// Before
29-
import { createParamDecorator } from '@nestjs/common';
18+
NATS has released a new major version (2.0) which has many changes and it is not API compatible with `[email protected]`.
19+
If you interact with a Nest microservice (that uses NATS as a transfer layer), from a service written in a different framework, please, see their [migration document](https://github.com/nats-io/nats.js/blob/master/migration.md) to learn what's changed in v2.
20+
Otherwise, you should not see any specific differences when communicating from one Nest microservice and another (although we use v2 now, there are no API differences - just make sure to upgrade the `nats` package: `npm i nats@latest`).
3021

31-
export const User = createParamDecorator((data, req) => {
32-
return req.user;
33-
});
22+
#### `@All()` decorator
3423

35-
// After
36-
import { createParamDecorator } from '@nestjs/common';
24+
Routes annotated with the `@All()` decorator will now map to the `router.all()` method instead of the `router.use()`.
3725

38-
export const User = createParamDecorator((data, ctx) => {
39-
const request = ctx.switchToHttp().getRequest();
40-
return request.user;
41-
});
42-
```
26+
#### Async listen/start methods
4327

44-
#### Microservices
28+
`listenAsync()` and `startAllMicroservicesAsync()` methods have been deprecated.
29+
Instead, simply use the `listen()` and `startAllMicroservices()` methods (they are `async` either way).
4530

46-
To avoid code duplication, the `MicroserviceOptions` interface has been removed from the `@nestjs/common` package. Therefore, now when you're creating a microservice (through either `createMicroservice()` or `connectMicroservice()` method), you should pass the type generic parameter to get code autocompletion.
31+
#### Socket.io
4732

48-
```typescript
49-
@@filename()
50-
// Before
51-
const app = await NestFactory.createMicroservice(AppModule);
33+
The `@nestjs/platform-socket.io` package was upgraded to use the `[email protected]` version (Nest v7 was based on the `socket.io` v2).
34+
To learn more, check out these articles: [Socket.io 3 Release](https://socket.io/blog/socket-io-3-release/) and [Socket.io 4 Release](https://socket.io/blog/socket-io-4-release/).
5235

53-
// After
54-
const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule);
55-
@@switch
56-
// Before
57-
const app = await NestFactory.createMicroservice(AppModule);
36+
#### `@nestjs/config` package
5837

59-
// After
60-
const app = await NestFactory.createMicroservice(AppModule);
61-
```
62-
63-
> info **Hint** The `MicroserviceOptions` interface is exported from the `@nestjs/microservices` package.
64-
65-
#### GraphQL
66-
67-
In the version 6 major release of NestJS, we introduced the code-first approach as a compatibility layer between the `type-graphql` package and the `@nestjs/graphql` module. Eventually, our team decided to reimplement all the features from scratch due to a lack of flexibility. To avoid numerous breaking changes, the public API is backward-compatible and may resemble `type-graphql`.
68-
69-
In order to migrate your existing application, simply rename all the `type-graphql` imports to the `@nestjs/graphql`. If you used more advanced features, you might need to also:
70-
71-
- use `Type` (imported from `@nestjs/common`) instead of `ClassType` (imported from `type-graphql`)
72-
- move methods that require `@Args()` from object types (classes annotated with `@ObjectType()` decorator) under resolver classes (and use `@ResolveField()` decorator instead of `@Field()`)
73-
74-
#### Terminus
75-
76-
In the version 7 major release of `@nestjs/terminus`, a new simplified API has been introduced
77-
to run health checks. The previously required peer dependency `@godaddy/terminus` has been removed, which allows us to integrate our health checks automatically into Swagger! Read more about the removal of `@godaddy/terminus` [here](https://github.com/nestjs/terminus/issues/340).
78-
79-
For most users, the biggest change will be the removal of the `TerminusModule.forRootAsync` function. With the next major version, this function will be completely removed.
80-
To migrate to the new API, you will need to create a new controller, which will handle your health checks.
81-
82-
```typescript
83-
@@filename()
84-
// Before
85-
@Injectable()
86-
export class TerminusOptionsService implements TerminusOptionsFactory {
87-
constructor(
88-
private http: HttpHealthIndicator,
89-
) {}
90-
91-
createTerminusOptions(): TerminusModuleOptions {
92-
const healthEndpoint: TerminusEndpoint = {
93-
url: '/health',
94-
healthIndicators: [
95-
async () => this.http.pingCheck('google', 'https://google.com'),
96-
],
97-
};
98-
return {
99-
endpoints: [healthEndpoint],
100-
};
101-
}
102-
}
103-
104-
@Module({
105-
imports: [
106-
TerminusModule.forRootAsync({
107-
useClass: TerminusOptionsService
108-
})
109-
]
110-
})
111-
export class AppModule { }
112-
113-
// After
114-
@Controller('health')
115-
export class HealthController {
116-
constructor(
117-
private health: HealthCheckService,
118-
private http: HttpHealthIndicator,
119-
) { }
120-
121-
@Get()
122-
@HealthCheck()
123-
healthCheck() {
124-
return this.health.check([
125-
async () => this.http.pingCheck('google', 'https://google.com'),
126-
]);
127-
}
128-
}
129-
130-
@Module({
131-
controllers: [
132-
HealthController
133-
],
134-
imports: [
135-
TerminusModule
136-
]
137-
})
138-
export class AppModule { }
139-
140-
@@switch
141-
142-
// Before
143-
@Injectable()
144-
@Dependencies(HttpHealthIndicator)
145-
export class TerminusOptionsService {
146-
constructor(
147-
private http,
148-
) {}
149-
150-
createTerminusOptions() {
151-
const healthEndpoint = {
152-
url: '/health',
153-
healthIndicators: [
154-
async () => this.http.pingCheck('google', 'https://google.com'),
155-
],
156-
};
157-
return {
158-
endpoints: [healthEndpoint],
159-
};
160-
}
161-
}
162-
163-
@Module({
164-
imports: [
165-
TerminusModule.forRootAsync({
166-
useClass: TerminusOptionsService
167-
})
168-
]
169-
})
170-
export class AppModule { }
171-
172-
// After
173-
@Controller('/health')
174-
@Dependencies(HealthCheckService, HttpHealthIndicator)
175-
export class HealthController {
176-
constructor(
177-
private health,
178-
private http,
179-
) { }
180-
181-
@Get('/')
182-
@HealthCheck()
183-
healthCheck() {
184-
return this.health.check([
185-
async () => this.http.pingCheck('google', 'https://google.com'),
186-
])
187-
}
188-
}
189-
190-
@Module({
191-
controllers: [
192-
HealthController
193-
],
194-
imports: [
195-
TerminusModule
196-
]
197-
})
198-
export class AppModule { }
199-
```
200-
201-
> warning **Warning** If you have set a [Global Prefix](faq#global-prefix) in your Nest application and you have not used the `useGlobalPrefix` Terminus option, the URL of your health check will change. Make sure to update the reference to that URL, or use the legacy Terminus API until [nestjs/nest#963](https://github.com/nestjs/nest/issues/963) is fixed.
202-
203-
If you are forced to use the legacy API, you can also disable deprecation messages for the time being.
204-
205-
```typescript
206-
TerminusModule.forRootAsync({
207-
useFactory: () => ({
208-
disableDeprecationWarnings: true,
209-
endpoints: [
210-
// ...
211-
]
212-
})
213-
}
214-
```
215-
216-
You should enable shutdown hooks in your `main.ts` file. The Terminus integration will listen on POSIX signals such as SIGTERM (see the [Application shutdown chapter](fundamentals/lifecycle-events#application-shutdown) for more information). When enabled, the health check route(s) will automatically respond with a Service Unavailable (503) HTTP error response when the server is shutting down.
217-
218-
With the removal of `@godaddy/terminus`, you will need to update your `import` statements
219-
to use `@nestjs/terminus` instead. Most notable is the import of the `HealthCheckError`.
220-
221-
```typescript
222-
@@filename(custom.health)
223-
// Before
224-
import { HealthCheckError } from '@godaddy/terminus';
225-
// After
226-
import { HealthCheckError } from '@nestjs/terminus';
227-
```
228-
229-
Once you have fully migrated, make sure you uninstall `@godaddy/terminus`.
230-
231-
```bash
232-
npm uninstall --save @godaddy/terminus
233-
```
234-
235-
##### `DNSHealthIndicator` deprecation
236-
237-
The `DNSHealthIndicator` has been renamed to `HttpHealthIndicator` in order to improve consistency with the official [`HttpService`](/techniques/http-module#http-module) as well as choosing a better fitting name for its functionality.
238-
239-
Simply migrate by replacing the `DNSHealthIndicator` references with `HttpHealthIndicator`. The functionality has been untouched.
240-
241-
```typescript
242-
// Before
243-
@Controller('health')
244-
export class HealthController {
245-
constructor(
246-
private dns: DNSHealthIndicator,
247-
) { }
248-
...
249-
}
250-
// After
251-
@Controller('health')
252-
export class HealthController {
253-
constructor(
254-
private http: HttpHealthIndicator,
255-
) { }
256-
...
257-
}
258-
```
259-
260-
#### HTTP exceptions body
261-
262-
Previously, the generated response bodies for the `HttpException` class and other exceptions derived from it (e.g., `BadRequestException` or `NotFoundException`) were inconsistent. In the latest major release, these exception responses will follow the same structure.
263-
264-
```typescript
265-
/*
266-
* Sample outputs for "throw new ForbiddenException('Forbidden resource')"
267-
*/
268-
269-
// Before
270-
{
271-
"statusCode": 403,
272-
"message": "Forbidden resource"
273-
}
274-
275-
// After
276-
{
277-
"statusCode": 403,
278-
"message": "Forbidden resource",
279-
"error": "Forbidden"
280-
}
281-
```
282-
283-
#### Validation errors schema
284-
285-
In past releases, the `ValidationPipe` threw an array of the `ValidationError` objects returned by the `class-validator` package. Now, `ValidationPipe` will map errors to a list of plain strings representing error messages.
286-
287-
```typescript
288-
// Before
289-
{
290-
"statusCode": 400,
291-
"error": "Bad Request",
292-
"message": [
293-
{
294-
"target": {},
295-
"property": "email",
296-
"children": [],
297-
"constraints": {
298-
"isEmail": "email must be an email"
299-
}
300-
}
301-
]
302-
}
303-
304-
// After
305-
{
306-
"statusCode": 400,
307-
"message": ["email must be an email"],
308-
"error": "Bad Request"
309-
}
310-
```
311-
312-
If you prefer the previous approach, you can restore it by setting the `exceptionFactory` function:
313-
314-
```typescript
315-
new ValidationPipe({
316-
exceptionFactory: (errors) => new BadRequestException(errors),
317-
});
318-
```
319-
320-
#### Implicit type conversion (`ValidationPipe`)
321-
322-
With the auto-transformation option enabled (`transform: true`), the `ValidationPipe` will now perform conversion of primitive types. In the following example, the `findOne()` method takes one argument which represents an extracted `id` path parameter:
323-
324-
```typescript
325-
@Get(':id')
326-
findOne(@Param('id') id: number) {
327-
console.log(typeof id === 'number'); // true
328-
return 'This action returns a user';
329-
}
330-
```
331-
332-
By default, every path parameter and query parameter comes over the network as a `string`. In the above example, we specified the `id` type as a `number` (in the method signature). Therefore, the `ValidationPipe` will try to automatically convert a string identifier to a number.
333-
334-
#### Microservice channels (bidirectional communication)
335-
336-
To enable the request-response message type, Nest creates two logical channels - one is responsible for transferring the data while the other waits for incoming responses. For some underlying transports, such as NATS, this dual-channel support is provided out-of-the-box. For others, Nest compensates by manually creating separate channels.
337-
338-
Let's say that we have a single message handler `@MessagePattern('getUsers')`. In the past, Nest built two channels from this pattern: `getUsers_ack` (for requests) and `getUsers_res` (for responses). With version 7, this naming scheme changes. Now Nest will build `getUsers` (for requests) and `getUsers.reply` (for responses) instead. Also, specifically for the MQTT transport strategy, the response channel would be `getUsers/reply` (to avoid conflicts with topic wildcards).
339-
340-
#### Deprecations
341-
342-
All deprecations (from Nest version 5 to version 6) have been finally removed (e.g., the deprecated `@ReflectMetadata` decorator).
343-
344-
#### Node.js
345-
346-
This release drops support for Node v8. We strongly recommend using the latest LTS version.
38+
There was a minor breaking change in the `registerAs` function (typings), you can see what has changed in [this PR](https://github.com/nestjs/config/pull/173).

0 commit comments

Comments
 (0)