こんにちは、エキサイト株式会社の平石です。
エキサイトホールディングス Advent Calendar 2023の22日目を担当いたします。
OpenAPI仕様に基づいてAPIの仕様を定義したYAMLファイルから、アプリ用のDartコードを自動生成する際に、タグの指定で注意すべき点がありました。
実際に、APIとアプリ側の繋ぎ込みを行なう際に問題となったため、ブログとして残しておこうと思います。
OpenAPIとは
本ブログでは、Dartコードを自動生成する部分の説明は省きます。
以下で紹介されていますので、こちらもご覧ください。
tech.excite.co.jp
タグに日本語は使わない方が良い?
結論から述べますと、タグに日本を指定してしまったことで、問題が発生しました。
以下で、日本語を指定することで発生する現象を詳細にご紹介します。
今回はYAMLファイルからコードを自動生成することを考えます。
以下のように、APIを定義したYAMLファイルを用意します。
openapi: 3.0.1
info:
title: OpenAPI definition
version: v0
servers:
- url: http://localhost:8190
description: Generated server url
paths:
/article:
get:
tags:
- 記事
summary: 記事取得
operationId: getArticle
responses:
"200":
description: 正常に処理が終了した場合
content:
application/text:
schema:
type: string
components: {}
余談ですが、このYAMLファイルは以下のようなSpringBoot製のControllerを持つAPIから生成しました。
@RestController
@RequestMapping("article")
@Tag(name = "記事")
public class ArticleGetController {
@GetMapping
@Operation(summary = "記事取得")
@ApiResponses(value = {
@ApiResponse(
responseCode = "200",
description = "正常に処理が終了した場合",
content = @Content(mediaType = "application/text", schema = @Schema(implementation = String.class))
)
})
public String getArticle() {
return "Article";
}
}
YAMLファイルの11, 12行目でtags
に「記事」というタグを指定しています。
この、tags
に指定した文字列によってエンドポイントが分類されます。
また、自動生成されるDartのコードの「どのクラスに、どのエンドポイントに対応するコードが生成されるか」もこのタグを元に決定されます。
しかし、このタグの設定に上記の「記事」のような英数字以外の文字を入れてしまうと、コード生成がうまくいきません。
この挙動を見てみましょう。
同じ「記事」というタグを設定した記事投稿のエンドポイントと、「ユーザー」というタグを設定したユーザー取得のエンドポイントの定義を追加してみます。
openapi: 3.0.1
info:
title: OpenAPI definition
version: v0
servers:
- url: http://localhost:8190
description: Generated server url
paths:
/article/post:
post:
tags:
- 記事
summary: 記事投稿
operationId: postArticle
responses:
"201":
description: 正常に処理が終了した場合
content:
application/text:
schema:
type: string
/user:
get:
tags:
- ユーザー
summary: ユーザー取得
operationId: getUser
responses:
"200":
description: 正常に処理が終了した場合
content:
application/text:
schema:
type: string
/article:
get:
tags:
- 記事
summary: 記事取得
operationId: getArticle
responses:
"200":
description: 正常に処理が終了した場合
content:
application/text:
schema:
type: string
components: {}
これらのエンドポイントを作成した上で、swagger-ui(http://localhost:8190/swagger-ui/index.html)を確認すると以下のようになっているはずです。
指定したタグによって、「記事」と「ユーザー」で分類がなされていることがわかります。
Swaggerまでは英数字以外のタグも認識してくれるようです。
それでは、アプリ用のDartコードを自動生成してみます。
OpenAPIを使って、Spring Boot製のAPIからアプリ用のDartコードを自動生成する - エキサイト TechBlog. の内容に従って、自動生成を行ないます。
すると、generated/dart/lib/src/api
配下にdefault_api.dart
ファイルが作成されます。
この中身を見ると、すべてのエンドポイントに対応するコードがdefault_api.dart
内に生成されてしまっています。
これは、タグを全く指定せずにコードを自動生成した時と同じ結果です。
一方、記事
→ article
、ユーザー
→ user
のように英数字のみを使うようにすると、以下のように2つのファイルに分かれて生成されます。
このように、dartファイルの自動生成の段階では。英数字のタグしか認識されず、日本語のタグは無視されてしまうようです。
タグがファイル名やクラス名の一部になるという仕様になっているようなので、当然と言えば当然の挙動かもしれません。
もう一つ、以下のような現象も発生します。
「記事API」「ユーザーAPI」というタグを設定した2つのエンドポイントを作成することを考えます。
〜 略 〜
paths:
/user:
get:
tags:
- ユーザーAPI
〜 略 〜
/article:
get:
tags:
- 記事API
〜 略 〜
「記事」と「ユーザー」という2つの異なる要素を扱うエンドポイントに対応する自動生成のコードが、別々のファイルに生成されることを期待した設定です。
しかし、この場合、api_api.dart
というファイルに2つのエンドポイントに対応するコードが生成されるという、予期しない動作をします。
日本語の部分(「記事」「ユーザー」)が無視され、英数字である「API」という部分だけが認識された結果、どちらも「API」というタグを指定した時と同じ結果になったと考えられます。
最も、全てのコードがdefault_api.dart
内等の同じファイルに生成されたとしても、実際のコードには動作上問題ありません。
しかし、自動生成されたコードが分類されていた方が、可読性や利便性の観点で優れていると考えられます。
そのため、タグの指定には英数字以外は使わないようにするのが無難でしょう。
終わりに
今回は、OpenAPI仕様のYAMLファイルからアプリ用のDartコードを自動生成する際には、タグの指定に注意する必要があるということを紹介しました。
では、また次回。