LoginSignup
4
1

More than 1 year has passed since last update.

NestJSでAPIをバージョニング管理する

Posted at

APIサーバーを構築していると、 APIの後方互換を持たせるために、/v1//v2/といったREST APIにバージョンを持たせると思います。

3年前にNestJSでAPIバージョニングをするという記事が書かれていますが、NestJS v8から、新しい機能として実装されましたので、その機能を紹介します。

手順

有効にする方法は至って簡単
次のコードを追加するだけ!

main.ts
const app = await NestFactory.create(AppModule);
+ app.enableVersioning({
+   type: VersioningType.URI,
+ });
await app.listen(3000);

Controllerに宣言するパターン

例えば次のようなコントローラー

user.controller.ts
+ @Controller({ version: ['1', '2'], path: 'users' })
+ // `https://api.example.com/v1/user` -> OK
+ // `https://api.example.com/v2/user` -> OK
+ // `https://api.example.com/v3/user` -> 404
export class UserController {
  constructor(private userService: UserService) {}

  @Get('/:id')
  findOneById(@Param('id') id: string) {
    return this.userService.findOneById(id)
  }

  @Post()
  async create(@Body() body: CreateUserDTO) {
    const result = await this.userService.create(body)
    return result
  }

  @Put('/:id')
  async update(@Body() body: UpdateUserDTO, @Param('id') id: string) {
    const result = await this.userService.update(id, body)
    return result
  }
}

Routeに宣言するパターン

user.controller.ts
@Controller('users')
export class UserController {
  constructor(private userService: UserService) {}

+ @Version(['1', '2'])
+ // `https://api.example.com/v1/user` -> OK
+ // `https://api.example.com/v2/user` -> OK
+ // `https://api.example.com/v3/user` -> 404
  @Get('/:id')
  findOneById(@Param('id') id: string) {
    return this.userService.findOneById(id)
  }

  @Post()
  async create(@Body() body: CreateUserDTO) {
    const result = await this.userService.create(body)
    return result
  }

  @Put('/:id')
  async update(@Body() body: UpdateUserDTO, @Param('id') id: string) {
    const result = await this.userService.update(id, body)
    return result
  }
}

デフォルトのバージョンを宣言する

defaultVersionを指定しておくと、全てのController、Routeにデフォルトのバージョンが宣言されます。

main.ts
const app = await NestFactory.create(AppModule);
 app.enableVersioning({
   type: VersioningType.URI,
+  defaultVersion: ['1', '2'],
 });
await app.listen(3000);

VERSION_NEUTRALについて

VERSION_NEUTRALを宣言した場合、そのAPIにはバージョンが宣言されません。

user.controller.ts
@Controller('users')
export class UserController {
  constructor(private userService: UserService) {}

+ @Version([VERSION_NEUTRAL])
+ // `https://api.example.com/user` -> OK
+ // `https://api.example.com/v1/user` -> 404
  @Get('/:id')
  findOneById(@Param('id') id: string) {
    return this.userService.findOneById(id)
  }

  @Post()
  async create(@Body() body: CreateUserDTO) {
    const result = await this.userService.create(body)
    return result
  }

  @Put('/:id')
  async update(@Body() body: UpdateUserDTO, @Param('id') id: string) {
    const result = await this.userService.update(id, body)
    return result
  }
}

公式ドキュメント

詳しくは公式ドキュメントがわかりやすいです。

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1