FlutterでAPIとしてGraphQLを利用する際の使用感を掴むために軽く調査したので、メモしておきます
使用するライブラリ
ドキュメントも作られていて、活発にメンテナンスされているようでしたので、ferryを採用しました
他にも graphql、graphql_flutter、artemis などが候補としてありましたが、記事執筆時点で、
- Stable版がNull-Safety対応していない
- フェッチしたデータの型付け処理のためのコードの自動生成に対応していない
- 動作が不安定っぽい
などの理由があったので、これらを利用するのはやめました
手順
GraphQLのサーバー
GraphQL Fakerを利用しました。
READMEに従ってサーバーを立てると、http://localhost:9002/graphqh
にGraphQLのエンドポイントが作られます
Flutterプロジェクト
ferry の導入
Flutterプロジェクトに、以下コマンドにより必要なパッケージを追加します。
flutter pub add ferry
flutter pub add gql_http_link
flutter pub add -d ferry_generator
flutter pub add -d build_runner
Dartコードの自動生成
GraphQL Faker でデフォルトで設定されているデータ構造のスキーマを lib/graphql/schema.graphql
として保存します。
type Company {
id: ID
name: String
industry: String
employees: [Employee!] @listLength(min: 5, max: 10)
}
type Employee {
id: ID
firstName: String
lastName: String
address: String
subordinates: [Employee!] @listLength(min: 0, max: 3)
company: Company
}
type Query {
employee(id: ID): Employee
company(id: ID): Company
allCompanies: [Company!]
}
データ取得のスキーマを lib/graphql/employee.query.graphql
として作成します。
query GetEmployees {
employee {
id
}
}
ビルド設定ファイルを build.yaml
として作成します。
以下はドキュメントの記述ほぼそのままです。
your_package_name
はプロジェクト名に置き換えます。
targets:
$default:
sources:
- lib/**
builders:
gql_build|schema_builder:
enabled: true
gql_build|ast_builder:
enabled: true
gql_build|data_builder:
enabled: true
options:
schema: your_package_name|lib/schema.graphql
gql_build|var_builder:
enabled: true
options:
schema: your_package_name|lib/schema.graphql
gql_build|serializer_builder:
enabled: true
options:
schema: your_package_name|lib/schema.graphql
ferry_generator|req_builder:
enabled: true
options:
schema: your_package_name|lib/schema.graphql
以下コマンドを実行し、GraphQL クライアントのコードを自動生成します。
flutter pub run build_runner build
API 呼び出しの実装
自動生成されたコードを利用して GraphQL の API を叩くクラスを、lib/graphql.dart
として以下のように作成します。
class GraphQlAPIClient {
late final Client _client;
GraphQlAPIClient() {
final link = HttpLink(
'http://localhost:9002/graphql',
);
this._client = Client(link: link);
}
void listenEmployees() async {
final request = GGetEmployeesReq();
_client.request(request).listen((event) {
final data = event.data;
if (data != null) {
print('Employee ID: ${data.employee?.id}');
}
});
}
}
あとは、適当な場所から用意したメソッドを呼び出します。
void main() {
final graphQlClient = GraphQlAPIClient();
graphQlClient.listenEmployees();
// ...
}
一点注意として、サーバーの向き先をlocalhost
にしているので、シミュレーターやエミュレーターでしか動かないコードになっています。
参考