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


本記事は、以前の以下の記事をバージョンアップしたものになります。
Spring Boot と Angular2 をタイプセーフに繋ぐ

課題になっていたこと

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

作ったもの

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

プロジェクトの構成

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

開発フロー

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

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

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

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 が自動生成されたクラスです。

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)