これは何?
Flutter アプリで OpenAPI Generator を使った開発する方法をまとめたもの
Open API Generator とは
OpenAPI Generator とは、OpenAPI Spec を元に、APIクライアントライブラリ(SDK生成)、サーバースタブ、ドキュメント、設定を自動的に生成することができるツールのことです。
これを使うこと以下のようなメリットがあります
- ドキュメントと実装が乖離しづらい
- 呼び元と呼び先の両方で使うデータの定義を自動生成できる
自動生成してみる
以下のようなディレクトリ構成でサンプルを作成しました
open-api-generator-example/
├ client-todo-api/ # OpenAPI Generator で自動生成されたファイル群
└ client/ # 開発をするFlutterアプリ
まずは自動生成のために使う API の定義を記述します
※ 環境: Flutter / 通信ライブラリに Dio を使用
※ Todoアプリをサンプルとして扱います
openapi: 3.0.0
servers:
- url: "http://localhost:8080/v1"
info:
version: 1.0.0
title: OpenAPI Example
paths:
/todos:
post:
summary: Add a new todo
description: ""
operationId: addTodo
responses:
"200":
description: successful operation
content:
application/json:
schema:
$ref: "#/components/schemas/Todo"
requestBody:
$ref: "#/components/requestBodies/Todo"
put:
summary: Update an existing todo
description: ""
operationId: updateTodo
responses:
"200":
description: successful operation
content:
application/json:
schema:
$ref: "#/components/schemas/Todo"
requestBody:
$ref: "#/components/requestBodies/Todo"
get:
summary: Finds todos
operationId: findTodos
responses:
"200":
description: successful operation
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/Todo"
externalDocs:
description: Find out more about Swagger
url: "http://swagger.io"
components:
requestBodies:
Todo:
content:
application/json:
schema:
$ref: "#/components/schemas/Todo"
description: Todo object that needs to be added to the store
required: true
schemas:
Todo:
title: a Todo
description: A todo
type: object
required:
- name
properties:
id:
type: integer
format: int64
name:
type: string
example: buy milk
status:
type: string
description: todo status
deprecated: true
enum:
- todo
- doing
- done
ApiResponse:
title: An uploaded response
description: Describes the result of uploading an image resource
type: object
properties:
code:
type: integer
format: int32
type:
type: string
message:
type: string
このまま自動生成すると pub name
が openapi
になります。
これだと複数APIあった時にどのAPIかわからなくなってしまうので client-config.yml
を作成し todo_api
に変更をします。
additionalProperties:
pubName: todo_api
これで設定は完了です。
以下のコマンドで自動生成をします。
docker run --rm -v ${PWD}:/local openapitools/openapi-generator-cli generate -i /local/todo.yaml -g dart-dio-next -o /local/client-todo-api -c /local/client-config.yml
client-todo-api
ディレクトリにコードが自動生成されました。
自動生成されたコードは以下のように呼び出すことができます。
final response = await TodoApi().getDefaultApi().addTodo(todo: todo);
eturn response.data;
アプリに組み込む
pubspec.yaml
を編集しアプリに組み込みます。
...
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^1.0.2
todo_api:
path: ../client-todo-api # 作成したディレクトリを相対パスで指定
これでアプリから自動生成したファイルを呼び出すことができるようになりました。
単純なAPIの呼び出しや、
import 'package:todo_api/todo_api.dart';
Future<Todo?> saveTodos(Todo todo) async {
final response = await TodoApi().getDefaultApi().addTodo(todo: todo);
return response.data;
}
Future<List<Todo>> fetchTodos() async {
final response = await TodoApi().getDefaultApi().findTodos();
return response.data?.toList() ?? [];
}
自動生成されたクラスのインスタンスの生成/変更ができます。
// 生成
final todo = Todo(
(b) => b
..id = 1
..name = 'name',
);
// 変更
final newTodo = todo.rebuild((b) => b..name = 'edited');
まとめ
OpenAPI Generator を使うことで API定義から Flutter アプリから呼び出すことのできるコードを自動生成することができました。
- ドキュメントと実装が乖離しづらい
- 呼び元と呼び先の両方で使うデータの定義を自動生成できる
というメリットがあるので、新規でアプリ開発をする場合は積極的に導入しようと思いました。