Skip to content

Commit 77da505

Browse files
feat(): add versioning chapter
1 parent 31e34bf commit 77da505

File tree

4 files changed

+47
-101
lines changed

4 files changed

+47
-101
lines changed

content/techniques/versioning.md

Lines changed: 30 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
### Versioning
22

3-
Versioning allows you to have different versions of your controllers or individual routes running within the same application. Applications change very often and it is not unusual that there are breaking changes that you need to make while still needing to support the previous version of the application.
3+
> info **Hint** This chapter is only relevant to HTTP-based applications.
4+
5+
Versioning allows you to have **different versions** of your controllers or individual routes running within the same application. Applications change very often and it is not unusual that there are breaking changes that you need to make while still needing to support the previous version of the application.
46

57
There are 3 types of versioning that are supported:
8+
69
<table>
7-
<tr>
8-
<th>Type</th>
9-
<th>Description</th>
10-
</tr>
1110
<tr>
1211
<td><a href='techniques/versioning#uri-versioning-type'><code>URI Versioning</code></a></td>
13-
<td>The version will be passed within the URI of the request</td>
12+
<td>The version will be passed within the URI of the request (default)</td>
1413
</tr>
1514
<tr>
1615
<td><a href='techniques/versioning#header-versioning-type'><code>Header Versioning</code></a></td>
@@ -28,27 +27,16 @@ URI Versioning uses the version passed within the URI of the request, such as `h
2827

2928
> warning **Notice** With URI Versioning the version will be automatically added to the URI after the <a href="faq/global-prefix">global path prefix</a> (if one exists), and before any controller or route paths.
3029
31-
Example HTTP Requests for URI Versioning:
32-
```http
33-
GET https://example.com/v1/route HTTP/1.1
34-
35-
GET https://example.com/v2/route HTTP/1.1
36-
```
37-
3830
To enable URI Versioning for your application, do the following:
3931

4032
```typescript
4133
@@filename(main)
42-
import { VersioningType } from '@nestjs/common';
43-
44-
async function bootstrap() {
45-
const app = await NestFactory.create(AppModule);
46-
app.enableVersioning({
47-
type: VersioningType.URI,
48-
});
49-
await app.listen(3000);
50-
}
51-
bootstrap();
34+
const app = await NestFactory.create(AppModule);
35+
// or "app.enableVersioning()"
36+
app.enableVersioning({
37+
type: VersioningType.URI,
38+
});
39+
await app.listen(3000);
5240
```
5341

5442
> warning **Notice** The version in the URI will be automatically prefixed with `v` by default, however the prefix value can be configured by setting the `prefix` key to your desired prefix or `false` if you wish to disable it.
@@ -60,29 +48,17 @@ bootstrap();
6048
Header Versioning uses a custom, user specified, request header to specify the version where the value of the header will be the version to use for the request.
6149

6250
Example HTTP Requests for Header Versioning:
63-
```http
64-
GET https://example.com/route HTTP/1.1
65-
Custom-Version-Header: 1
6651

67-
GET https://example.com/route HTTP/1.1
68-
Custom-Version-Header: 2
69-
```
70-
71-
To enable Header Versioning for your application, do the following:
52+
To enable **Header Versioning** for your application, do the following:
7253

7354
```typescript
7455
@@filename(main)
75-
import { VersioningType } from '@nestjs/common';
76-
77-
async function bootstrap() {
78-
const app = await NestFactory.create(AppModule);
79-
app.enableVersioning({
80-
type: VersioningType.HEADER,
81-
header: 'Custom-Header',
82-
});
83-
await app.listen(3000);
84-
}
85-
bootstrap();
56+
const app = await NestFactory.create(AppModule);
57+
app.enableVersioning({
58+
type: VersioningType.HEADER,
59+
header: 'Custom-Header',
60+
});
61+
await app.listen(3000);
8662
```
8763

8864
The `header` property should be the name of the header that will contain the version of the request.
@@ -95,30 +71,16 @@ Media Type Versioning uses the `Accept` header of the request to specify the ver
9571

9672
Within the `Accept` header, the version will be separated from the media type with a semi-colon, `;`. It should then contain a key-value pair that represents the version to use for the request, such as `Accept: application/json;v=2`. They key is treated more as a prefix when determining the version will to be configured to include the key and separator.
9773

98-
Example HTTP Requests for Media Type Versioning:
99-
```http
100-
GET https://example.com/route HTTP/1.1
101-
Accept: application/json;v=1
102-
103-
GET https://example.com/route HTTP/1.1
104-
Accept: application/json;v=2
105-
```
106-
107-
To enable Media Type Versioning for your application, do the following:
74+
To enable **Media Type Versioning** for your application, do the following:
10875

10976
```typescript
11077
@@filename(main)
111-
import { VersioningType } from '@nestjs/common';
112-
113-
async function bootstrap() {
114-
const app = await NestFactory.create(AppModule);
115-
app.enableVersioning({
116-
type: VersioningType.MEDIA_TYPE,
117-
key: 'v=',
118-
});
119-
await app.listen(3000);
120-
}
121-
bootstrap();
78+
const app = await NestFactory.create(AppModule);
79+
app.enableVersioning({
80+
type: VersioningType.MEDIA_TYPE,
81+
key: 'v=',
82+
});
83+
await app.listen(3000);
12284
```
12385

12486
The `key` property should be the key and separator of the key-value pair that contains the version. For the example `Accept: application/json;v=2`, the `key` property would be set to `v=`.
@@ -131,16 +93,14 @@ Versioning allows you to version controllers, individual routes, and also provid
13193

13294
> warning **Notice** If versioning is enabled for the application but the controller or route does not specify the version, any requests to that controller/route will be returned a `404` response status. Similarly, if a request is received containing a version that does not have a corresponding controller or route, it will also be returned a `404` response status.
13395
134-
#### Controller Versions
96+
#### Controller versions
13597

13698
A version can be applied to a controller, setting the version for all routes within the controller.
13799

138100
To add a version to a controller do the following:
139101

140102
```typescript
141103
@@filename(cats.controller)
142-
import { Controller, Get } from '@nestjs/common';
143-
144104
@Controller({
145105
version: '1',
146106
})
@@ -150,19 +110,7 @@ export class CatsControllerV1 {
150110
return 'This action returns all cats for version 1';
151111
}
152112
}
153-
154-
@Controller({
155-
version: '2',
156-
})
157-
export class CatsControllerV2 {
158-
@Get('cats')
159-
findAll(): string {
160-
return 'This action returns all cats for version 2';
161-
}
162-
}
163113
@@switch
164-
import { Controller, Get } from '@nestjs/common';
165-
166114
@Controller({
167115
version: '1',
168116
})
@@ -172,19 +120,9 @@ export class CatsControllerV1 {
172120
return 'This action returns all cats for version 1';
173121
}
174122
}
175-
176-
@Controller({
177-
version: '2',
178-
})
179-
export class CatsControllerV2 {
180-
@Get('cats')
181-
findAll() {
182-
return 'This action returns all cats for version 2';
183-
}
184-
}
185123
```
186124

187-
#### Route Versions
125+
#### Route versions
188126

189127
A version can be applied to an individual route. This version will override any other version that would effect the route, such as the Controller Version.
190128

@@ -227,18 +165,14 @@ export class CatsController {
227165
}
228166
```
229167

230-
> info **Hint** The `@Version()` decorator is imported from `@nestjs/common` package.
231-
232-
#### Multiple Versions
168+
#### Multiple versions
233169

234170
Multiple versions can be applied to a controller or route. To use multiple versions, you would set the version to be an Array.
235171

236172
To add multiple versions do the following:
237173

238174
```typescript
239175
@@filename(cats.controller)
240-
import { Controller, Get } from '@nestjs/common';
241-
242176
@Controller({
243177
version: ['1', '2'],
244178
})
@@ -249,8 +183,6 @@ export class CatsController {
249183
}
250184
}
251185
@@switch
252-
import { Controller, Get } from '@nestjs/common';
253-
254186
@Controller({
255187
version: ['1', '2'],
256188
})
@@ -262,8 +194,7 @@ export class CatsController {
262194
}
263195
```
264196

265-
266-
#### Version Neutral
197+
#### Version "Neutral"
267198

268199
Some controllers or routes may not care about the version and would have the same functionality regardless of the version. To accommodate this, the version can be set to `VERSION_NEUTRAL` symbol.
269200

@@ -284,7 +215,7 @@ export class CatsController {
284215
@Get('cats')
285216
findAll(): string {
286217
return 'This action returns all cats regardless of version';
287-
}
218+
}
288219
}
289220
@@switch
290221
import { Controller, Get, VERSION_NEUTRAL } from '@nestjs/common';
@@ -299,5 +230,3 @@ export class CatsController {
299230
}
300231
}
301232
```
302-
303-
> info **Hint** The `VERSION_NEUTRAL` symbol is imported from `@nestjs/common` package.

src/app/homepage/menu/menu.component.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ export class MenuComponent implements OnInit {
9292
{ title: 'Validation', path: '/techniques/validation' },
9393
{ title: 'Caching', path: '/techniques/caching' },
9494
{ title: 'Serialization', path: '/techniques/serialization' },
95+
{ title: 'Versioning', path: '/techniques/versioning' },
9596
{ title: 'Task scheduling', path: '/techniques/task-scheduling' },
9697
{ title: 'Queues', path: '/techniques/queues' },
9798
{ title: 'Logging', path: '/techniques/logger' },

src/app/homepage/pages/techniques/techniques.module.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { SqlComponent } from './sql/sql.component';
2121
import { StreamingFilesComponent } from './streaming-files/streaming-files.component';
2222
import { TaskSchedulingComponent } from './task-scheduling/task-scheduling.component';
2323
import { ValidationComponent } from './validation/validation.component';
24+
import { VersioningComponent } from './versioning/versioning.component';
2425

2526
const routes: Routes = [
2627
{
@@ -124,6 +125,11 @@ const routes: Routes = [
124125
component: ServerSentEventsComponent,
125126
data: { title: 'Server-Sent Events' },
126127
},
128+
{
129+
path: 'versioning',
130+
component: VersioningComponent,
131+
data: { title: 'Versioning' },
132+
},
127133
{
128134
path: 'events',
129135
component: EventsComponent,
@@ -151,6 +157,7 @@ const routes: Routes = [
151157
HttpModuleComponent,
152158
ConfigurationComponent,
153159
CompressionComponent,
160+
VersioningComponent,
154161
ValidationComponent,
155162
CachingComponent,
156163
SerializationComponent,
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { ChangeDetectionStrategy, Component } from '@angular/core';
2+
import { BasePageComponent } from '../../page/page.component';
3+
4+
@Component({
5+
selector: 'app-versioning',
6+
templateUrl: './versioning.component.html',
7+
changeDetection: ChangeDetectionStrategy.OnPush,
8+
})
9+
export class VersioningComponent extends BasePageComponent {}

0 commit comments

Comments
 (0)