🦁
Nest.js Version8がリリースされたので新機能についてまとめる : API Versioning編
Nest.js Version 8が7月7日にリリース!
新機能: API Versioning
Controller及び各Routesをバージョン管理できるようになりました。
1.URI Versioning
URIの中にVersion情報を含める。
import { VersioningType } from '@nestjs/common';
const app = await NestFactory.create(AppModule);
app.enableVersioning({
type: VersioningType.URI,
});
// OK!! http://localhost:3000/v1
Version管理の細かい話などはSemantic Versioning等を参照するといいかもしれない。
prefixは明示に指定しない限りv1,v2となるようです。
import { VersioningType } from '@nestjs/common';
const app = await NestFactory.create(AppModule);
app.enableVersioning({
type: VersioningType.URI,
//ここで別途prefixを指定できる。
prefix:"ver"
// OK!! http://localhost:3000/ver1
// Error!! http://localhost:3000
});
2.Header Versioning
headerで指定したrequest headerにversion情報を含める。
app.enableVersioning({
type: VersioningType.HEADER,
header: 'x-Api-Version',
});
requestにカスタムヘッダーを追加するmiddleware
import { Injectable, NestMiddleware } from '@nestjs/common';
import { Request, NextFunction } from 'express';
@Injectable()
export class VersioningMiddleware implements NestMiddleware {
use(req: Request, next: NextFunction) {
req.headers['x-API-Versioning'] = API_VERSION
next();
}
}
3.MediaType Versioning
Request時Accept HeaderにVerison情報を含める。
app.enableVersioning({
type: VersioningType.MEDIA_TYPE,
key: 'v=',
});
Version情報はセミコロンで区切る。
上記例の場合、Accept HeaderをAccept: application/json;v=1
という風に指定する。
Version指定
Controllerにversionを宣言するやり方と、各Routeにversionを宣言するやり方がある。
import { Controller, Get, Version } from '@nestjs/common';
import { AppService } from './app.service';
@Controller({ version: '1' })
export class AppController {
constructor(private readonly appService: AppService) {}
@Get()
getHello(): string {
return this.appService.getHello();
}
// OK!! http://localhost:3000/v1
// Error!! http://localhost:3000/v2
@Get('/bye')
@Version('2')
getBye() {
return this.appService.getBye();
}
// OK!! http://localhost:3000/bye/v2
// Error!! http://localhost:3000/bye/v1
}
Controllerのバージョン宣言より、各Routesのversion宣言が優先されます。
従って現状Controllerでメジャーバージョンを、Routesでマイナーバージョンを管理。
といった運用はできないみたいです。
また、Versionは配列で指定したり、そもそもVersion管理をする必要が無いEndpointには
VERSION_NEUTRAL
を指定することも可能です。
import { Controller, Get, Version, VERSION_NEUTRAL } from '@nestjs/common';
import { AppService } from './app.service';
@Controller({ version: ['1', '2'] })
export class AppController {
constructor(private readonly appService: AppService) {}
@Get()
getHello(): string {
return this.appService.getHello();
}
// OK!! http://localhost:3000/v1
// OK!! http://localhost:3000/v2
@Get('/bye')
@Version(VERSION_NEUTRAL)
getBye() {
return this.appService.getBye();
}
}
// OK!! http://localhost:3000/bye
// Error!! http://localhost:3000/bye/v1
最後に
API Versioning自体は賛否両論ありますが、Nest.jsという個人的に好きなFWにメジャーアップデートが来たのが何よりうれしいですね!!
他にもV8の新機能としてServerless環境での運用の際に役立ちそうなlazy-loadingや,
Log機能にもアップデートが入ってるみたいなので後日まとめようと思います!
Discussion