👩‍💻

OpenAPI定義からソースコードを自動生成するまでをリポジトリにまとめてみた

2024/11/10に公開

要約

はじめに

以前からAPI関連をまとめるのにOpenAPI(Swagger)が利用されているプロジェクトや記事を見ており、個人的に興味が湧いたため、「OpenAPIでAPI定義作成〜ソースコードの自動生成」までを実施してみました。
また、OpenAPIをプロジェクトに取り入れた「スキーマ駆動開発」について発表する機会があったため、良い機会だと思いまとめてみました。

そもそもOpenAPIとは

OpenAPIというワードを初めて聴くエンジニアは少ないと思う。
が、「OpenAPIって何?」と問われると答えられるエンジニアは減ってくるのではないかと。
もれなく私も減る側の人間でした。

ご本家様: OpenAPI Specification

The OpenAPI Specification (OAS) defines a standard, language-agnostic interface to HTTP APIs which allows both humans and computers to discover and understand the capabilities of the service without access to source code, documentation, or through network traffic inspection. When properly defined, a consumer can understand and interact with the remote service with a minimal amount of implementation logic.

要は
API定義をソースコード管理できたら便利だよね?
って感じたプロジェクトで使うと良さそう。

OpenAPI.yamlファイルの作成

実際にOpenAPIを利用して定義ファイルを作成してみた。
OpenAPI定義はJSONorYAML形式で記述できるが、今回は可読性が高いYAML形式を採用。

定義ファイルはエンドポイントごとに分けたかったので、ディレクトリ構成はこんな感じ。

.
├── README.md
└── spec
    ├── config.json
    ├── openapi.yaml
    └── path
        ├── sample-user-userId.yaml
        └── sample-users.yaml

実際の記述内容はこんな感じ。(一部抜粋)

spec/openapi.yaml

openapi: 3.0.0
info:
  title: API一覧
  description: サンプルAPI一覧です。
  version: 1.0.0
servers:
  - url: http://localhost:2131/
    description: The Local API server
paths:
  /api/sample-users:
    $ref: "./path/sample-users.yaml"
  /api/sample-users/{userId}:
    $ref: "./path/sample-user-userId.yaml"

spec/path/sample-users.yaml

get:
  summary: サンプルユーザー情報取得
  operationId: getSampleUsers
  tags:
    - SAMPLE
  responses:
    "200":
      description: ユーザー情報取得成功
      content:
        application/json:
          schema:
            type: array
            items:
              type: object
              properties:
                name:
                  type: string
                  example: "John Doe"
                email:
                  type: string
                  example: "john.doe@example.com"
                age:
                  type: integer
                  example: 30
                createdAt:
                  type: string
                  format: date-time
                  example: "2024-07-01 12:00:00"
                updatedAt:
                  type: string
                  format: date-time
                  example: "2024-07-01 12:00:00"

VSCodeでプレビュー表示するとこんな感じ
すごく良い!!見やすいね
alt text

ソースコード自動生成

ここまででOpenAPIを利用したAPIの定義ファイルを生成した。

しかしここで終了はもったいない。

この定義をもとに、ソースコードの自動生成まで対応してみた。

ソースコードの自動生成までの実行コマンドはこんな感じ。

docker run --rm -v $(pwd):/local openapitools/openapi-generator-cli:v7.7.0 generate -i /local/spec/openapi.yaml -g typescript-axios -c /local/spec/config.json -o /local/build/frontend

長い!!!!!!!!
ので、Shellにまとめました。(それぞれ長いで割愛)

Shellすらも打つの面倒臭い!!!!!!!!
のでMakefileを作りました。

.PHONY: generate-backend-api generate-frontend-api generate-all

generate-backend-api:
	sh generator/generate-backend.sh

generate-frontend-api:
	sh generator/generate-frontend.sh

generate-all: generate-backend-api generate-frontend-api

実際にコマンドを実行してみたらこんな感じ

% make generate-all
sh generator/generate-backend.sh
========== [START] OpenAPI Generator: backend ==========
[info] バリデーションチェック START
Validating spec (/local/spec/openapi.yaml)
No validation issues detected.
[info] バリデーションチェック OK
[info] コード生成 START
[main] INFO  o.o.codegen.DefaultGenerator - Generating with dryRun=false
[main] INFO  o.o.codegen.DefaultGenerator - OpenAPI Generator: php (client)
[main] INFO  o.o.codegen.DefaultGenerator - Generator 'php' is considered stable.
~
[info] コード生成に成功し��した
[info] コード生成 OK
========== [FINISH] OpenAPI Generator: backend ==========
sh generator/generate-frontend.sh
========== [START] OpenAPI Generator: frontend ==========
[info] バリデーションチェック START
Validating spec (/local/spec/openapi.yaml)
No validation issues detected.
[info] バリデーションチェック OK
[info] コード生成 START
[main] INFO  o.o.codegen.DefaultGenerator - Generating with dryRun=false
[main] INFO  o.o.codegen.DefaultGenerator - OpenAPI Generator: typescript-axios (client)
~
[info] コード生成に成功しました
[info] コード生成 OK
========== [FINISH] OpenAPI Generator: frontend =========
% 

最終的なディレクトリ構成

OpenAPI定義ファイルやら、自動生成用Shellやら、Shell実行用のMakefileやらを追加していき、
最終的にディレクトリ構成はこのようになりました。

.
├── Makefile
├── README.md
├── build
│   ├── backend
│   ├── frontend
├── doc
│   └── スキーマ駆動開発について.pdf
├── generator
│   ├── generate-backend.sh
│   └── generate-frontend.sh
└── spec
    ├── config.json
    ├── openapi.yaml
    └── path
        ├── sample-user-userId.yaml
        └── sample-users.yaml

ちなみにスキーマ駆動開発についてまとめたPDFは、自分が他のエンジニアの人に紹介したりする際に利用したファイルです。
紹介用に綺麗にまとめたつもりなので、よければご参照ください。

現時点の所感

API定義ファイルの作成までは良い感じでした。
VSCodeでのビューも非常にみやすくて良い!
そして何より、API定義をGit管理しやすくなったことが大きい!

ただ、自動生成されたソースコードがイマイチなところあり...。
具体的には、API実行時の戻り値の型が200だけを想定していたり、バリデーションチェックまで生成してくれなかったり...。

ここら辺はもう少し運用だったり使い方を考えないとしないといけない。

自分の実力不足含めて、現時点の所感は「75点」!

引き続き、OpenAPIやらスキーマ駆動開発について勉強していきます。

GitHubで編集を提案

Discussion