openapi_generator使ってみた
Note(ノート)
openapi_generatorがよく使われているのが流行りかなと思い勉強してみました。dioを使用してAPI通信するコードを自動生成してくれる便利なものですね。
This library is the dart/flutter implementation of openapi client sdk code generation.
With this library, you can generate openapi client sdk libraries from your openapi specification right in your flutter/dart projects. (see example)
To be used together with openapi-generator-annotations
このライブラリはopenapiクライアントSDKコード生成のdart/flutter実装です。
このライブラリを使うと、openapi仕様からopenapiクライアントSDKライブラリをflutter/dartプロジェクト内で生成することができます。
developブランチバージョンもあります。
openapi-generator-annotationと一緒に使うライブラリ
他にもその他多数あります。
pathなるものはファイルを自動生成した後に追加する。
openapi:
path: ./api # 生成されたapiフォルダへのパスを追加
settings file
試行錯誤して作ったのでバージョン古いの混ざってるかも?
公式のファイルだと複雑でわからなかった(^_^;)
name: open_generator_sample
description: "A new Flutter project."
publish_to: 'none'
version: 1.0.0+1
environment:
sdk: ^3.6.1
dependencies:
built_collection: ^5.1.1
flutter:
sdk: flutter
openapi_generator_annotations: ^6.1.0
dio: ^5.4.1
json_annotation: ^4.9.0
cupertino_icons: ^1.0.8
openapi:
path: ./api # 生成されたapiフォルダへのパスを追加
dev_dependencies:
flutter_test:
sdk: flutter
build_runner: ^2.4.14
openapi_generator: ^6.1.0
json_serializable: ^6.7.1
flutter_lints: ^5.0.0
flutter:
uses-material-design: true
このエンドポイントのJSONをYAMLで書く
openapi.yamlを作成する。
openapi: 3.0.0
info:
title: Post API
version: 1.0.0
description: API for managing posts
servers:
- url: https://jsonplaceholder.typicode.com
description: JSONPlaceholder API
paths:
/posts:
get:
summary: Get all posts
responses:
'200':
description: Successful response
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Post'
/posts/{id}:
get:
summary: Get a post by ID
parameters:
- name: id
in: path
required: true
schema:
type: integer
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/Post'
components:
schemas:
Post:
type: object
properties:
userId:
type: integer
id:
type: integer
title:
type: string
body:
type: string
required:
- userId
- id
- title
- body
configファイルを作成する。
// Openapi Generator last run: : 2025-02-07T18:36:57.311673
import 'package:openapi_generator_annotations/openapi_generator_annotations.dart';
// Openapi Generatorの設定
(
additionalProperties: AdditionalProperties(
pubName: 'openapi', // 生成するパッケージ名
pubAuthor: 'Your Name', // 生成するパッケージの作者名
),
inputSpec: InputSpec(path: 'openapi.yaml'), // 生成するAPIの設定ファイル
generatorName: Generator.dio, // 生成するAPIのライブラリ
outputDirectory: 'api', // 生成するAPIのディレクトリ
)
// 生成するAPIの設定
class ApiConfig {
static const String baseUrl = 'https://jsonplaceholder.typicode.com';
}
ファイルを自動生成する:
flutter pub run build_runner watch --delete-conflicting-outputs
HTTP GETを早速やってみよう。
import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
import 'package:openapi/openapi.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final api = DefaultApi(
Dio()..options.baseUrl = 'https://jsonplaceholder.typicode.com',
standardSerializers,
);
Future<List<Post>> fetchPosts() async {
final response = await api.postsGet();
return response.data!.toList();
}
void initState() {
super.initState();
fetchPosts();
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
body: FutureBuilder<List<Post>>(
future: fetchPosts(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(child: CircularProgressIndicator());
}
if (snapshot.hasError) {
return Center(child: Text('エラー: ${snapshot.error}'));
}
final posts = snapshot.data!;
return ListView.builder(
itemCount: posts.length,
itemBuilder: (context, index) {
final post = posts[index];
return ListTile(
title: Text(post.title),
subtitle: Text(post.body),
);
},
);
},
),
);
}
}
Que(きっかけ)
昔仕事で使ったことあったので個人的に使ってみたいなと思って試してみた。
フィットネスアプリを開発する案件で使われていてこれどうなってるんだろう???
当時はさっぱりわからなかった。既存のコードはyamlファイルに定義されているスキーマー通りに自動生成されるのでただ使うだけでよかった。
いやー難しい(^_^;)
Swagger Viewerというのもあるので試してみてね。yamlファイルで Shift + Alt + P
Summary(要約)
OpenAPI仕様(OAS)は、HTTP APIのための標準的な言語に依存しないインターフェースを定義するものです。これにより、ソースコード、ドキュメント、またはネットワークトラフィックの検査なしでも、人間とコンピュータの両方がサービスの機能を発見し理解することができます。適切に定義されていれば、利用者は最小限の実装ロジックで、リモートサービスを理解し、相互作用することができます。
OpenAPI定義は以下のような様々な用途に活用できます:
- ドキュメント生成ツールによるAPI仕様の表示
- 様々なプログラミング言語でのサーバーやクライアントコードの自動生成
- テストツールでの利用
- その他多くのユースケース
Discussion