OpenAPI Generator で Spring Boot と Angular をタイプセーフに繋ぐ

本記事は、以前の以下の記事をバージョンアップしたものになります。
[Spring Boot と Angular2 をタイプセーフに繋ぐ](https://tc.hatenablog.com/entry/2017/01/02/185917)

## 課題になっていたこと

Web バックエンドと Web フロントエンドで、JSON でボヤッっと緩く通信している状況が怖かった。
ビルド時にできるだけ、問題を検出したかった。
RPC的にタイプセーフに通信できるようにしたかった。

## 前回の構成から色々バージョンアップ

|  | 旧  | 新  |
|:--|:----|:----|
| backend の言語 | Java8 | Java11 |
| backend framework | Spring Boot 1 | Spring Boot 2 |
| frontend framework | Angular5 | Angular7 |
| コード生成ツール | Swagger Codegen | OpenAPI Generator |

[OpenAPI Generator](https://openapi-generator.tech) や Swagger Codegen は、REST API の仕様を基にクライアントコードや、サーバのスタブコードを生成するツールです。
残念なことに Swagger Codegen の運営？に問題があったらしく、トップコントリビュータによりフォークされ、OpenAPI Generator が誕生していました。
現状は、OpenAPI Generator の方が、コミット数、コントリビュータ数も多い状況です。
今回、 OpenAPI Generator に切り替えてみました。

## 作ったもの

雛形プロジェクトです。
https://github.com/chibat/spring-openapi-angular-starter

## プロジェクトの構成

<img src="https://docs.google.com/drawings/d/e/2PACX-1vSxXwLG6sgD4_NhSHS4cT3R2geZeDDz2lMDlSYnecIG77jE-Eu9KRdFYrLeMLV6LyBY6Ftft09APNHQ/pub?w=632&h=367">

OpenAPI の Spec ファイルは、SpringFox により自動で生成されるため手動で作成する必要がありません。

## 開発フロー

雛形プロジェクトに含まれる簡単な足し算アプリを例に説明します。

### 1. Web バックエンドの作成

Web バックエンドは、Spring Boot で作成します。
２つの整数をリクエストで受け取り、足してレスポンスするだけの Controller クラスです。

```java
package app.backend.web;

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.annotations.ApiOperation;
import lombok.Data;
import lombok.Value;

@RestController
public class CalculatorController {

    @PostMapping("/rest/api/add")
    @ApiOperation(value = "", tags = "calculator", nickname = "add")
    public Response add(@RequestBody final Request request) {
        return new Response(request.getArg1() + request.getArg2());
    }

    @Data
    public static class Request {
        private Integer arg1;
        private Integer arg2;
    }

    @Value
    public static class Response {
        private final Integer result;
    }
}
```
特記すべき点は、ApiOperation アノテーションで、tags で指定した文字列が生成されるクライアントのクラス名、 nickname で指定した文字列がメソッド名として使用されます。
また、nickname は、OpenAPI Spec の operationId として扱われ、全体でユニークにしないとダメっぽいです。

### 2. Web フロントエンドのクライアントコードの生成

Gradle のタスクを実行し、クライアントコードを生成します。

```
$ cd backend
$ ./gradlew openApiGenerate
```

テストが実行され、SpringFox の出力するAPIスペックが、ファイルに出力されます。
そのファイルを OpenAPI Generator が読み込み、クライアントコードを生成します。

SpringFox への依存は、テスト時のみで実行時のアプリケーションのサイズは増えません。

### 3. Web フロントエンドの作成

Web フロントエンドは、 Angular で作成します。
生成したクライアントコードを利用する Component クラスを作成します。
CalculatorService が自動生成されたクラスです。

```typescript
import { Component } from '@angular/core';
import { CalculatorService } from './client/api/calculator.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {

  arg1: number;
  arg2: number;
  result: number;

  constructor(private  calculatorService: CalculatorService) {
  }

  add() {
    if (this.arg1 || this.arg2) {
      this.calculatorService
        .add({arg1: this.arg1, arg2: this.arg2})
        .subscribe(data => this.result = data.result);
    }
  }
}
```

## まとめ

OpenAPI Generator 良い。
生成される Angular のコードも良い。
以上、快適なタイプセーフライフをお楽しみください。

## OpenAPI Generator の電子書籍が発売されました！（2019-09-19 追記）

OpenAPI Generator の電子書籍が発売されました。
興味のある方は、ご購入してみてはいかがでしょうか。

[REST API のためのコード生成入門 (OpenAPI Generator) ](https://gumroad.com/l/openapi_generator_ebook_jp)
<a href="https://gumroad.com/l/openapi_generator_ebook_jp"><img src="https://static-2.gumroad.com/res/gumroad/3680469107511/asset_previews/f359f63a4feaf3abf15e1046515adf79/retina/ebook_20cover_20japanese-page-001.jpg" width="300px"></a>