4
1

More than 1 year has passed since last update.

FlutterでSwagger(openapi-generator)を使う方法

Last updated at Posted at 2022-01-07

Flutterを使いアプリを作るのに、、APIと連携する部分はswaggerから自動生成したいと考え、openapi-generatorを使うことにしました。
ちなみに、Flutterは、始めたばかりでよくわからず、なんとなく動けばいいかくらいでやってます。。

いくつか参考になりそうなページがあったのですが、その中でも、
Flutter Swagger統合が、わかりやすくサンプルコードもあったのでこちらを参考に実装してみました。

試した環境

  • Flutter 2.5.3
  • Dart 2.14.4
  • Swagger 3.0.0

事前準備

通信するAPIを事前に作っておいて、それをローカルで起動します。
URL:http://localhost:31180/user
メソッド:POST
リクエスト:なし
で実行する簡易的なAPIを用意しました。
swaggerも作成します。
実際のswaggerから、今回必要な箇所を抜粋したのが以下です。

swagger.yaml
openapi: 3.0.0
info:
  title: sample
  version: '1.0'
  description: sample
  contact:
    name: murapon
servers:
  - url: 'http://localhost:31180'
tags:
  - name: user
paths:
  /user:
    post:
      operationId: post-user
      tags:
        - user
      summary: ユーザー登録
      description: ユーザーを作成し、uuid等を返す
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/response_user_post'
components:
  schemas:
    response_user_post:
      title: response_user_post
      description: ユーザー作成APIのレスポンスモデル
      type: object
      properties:
        uuid:
          type: string
          description: UUID
        password:
          type: string
          description: パスワード
      required:
        - uuid
        - password

ライブラリーのインストール

openapi-generatorインストール
こちらは参考にしたページ通りインストールするだけです。

swaggerからflutter用コードを生成

事前に、静的なページを表示するFlutterアプリは作っていたので、そこに生成しました。

openapi-generator generate -i ./openapi/definitions/sample.yaml -g dart -o ./openapi/generated/client/

で入れられます。
ここも参考ページ通りです。sample.yaml部分は、作ったswaggerファイル名に書き換えてください。
生成したら、
sh flutter pub get

を実行してください。

APIの実行コードの作成

APIを実行するコードは、参考ページのをそのまま使うとエラーになったので、以下のように変えました。

api.dart
import 'package:openapi/api.dart';

class sample {

  test() async {
// ① ベースとなるAPIクライアント生成
    var client = ApiClient(basePath: "http://10.0.2.2:31180");
// ヘッダを追加したい場合はクライアントに設定可能
//  client.addDefaultHeader("key", "value");

// ② APIクライアントラッパーを生成
// APIレスポンスをモデルに変換してくれる
    var api = UserApi(client);

// ③ レスポンスボディのみが欲しい場合は${HTTPメソッド名+パス名}のメソッドをcall
    ResponseUserPost user = await api.postUser('');
    print(user.toJson());
  }
}

まず、①の接続先URLが、localhostになっていたのですが、Androidシミュレータだとうまくいかなったので、
https://sunnyday-travel-aso-6487.ssl-lolipop.jp/programing/flutter/socketexception/
を参考に、10.0.2.2に変えました。
あと、③のapi.healthGet();が、パス名+HTTPメソッド名という並びになってたのですが、実際に生成されたソースを見ると、HTTPメソッド名+パス名という逆順になっていたのでそこを変えました。
(ライブラリーのバージョンの違いによる?)
また、レスポンスボディを取得するのが、valueだとうまくいかず、生成されたソースにあるtoJsonを使うと取得することができました。

APIを実行したい画面を表示しているソースに

samle_page.dart
Widget build(BuildContext context) {
・・・
  try{
    var a = new sample();
    a.test();
  } catch (e) {
    print(e.toString());
  }
・・・
}

のように書くと、とりあえず動くことを確認できます。
try,catchはなくてもいいのですが、あるとエラーを検出してくれます。
APIで返される項目名や型が、swaggerの定義と違うと処理できないのですが、その時のエラーは、try,catchを使ってないと検出できませんでした。

HTTPステータスコードをチェックしたい時

レスポンス結果だけを取得したい場合は、

ResponseUserPost user = await api.postUser('');

と、postUserを使うとよいのですが、エラー時などにHTTPステータスコードをチェックし処理を変えたい場合は、

ResponseUserPost user = await api.postUserWithHttpInfo('');

と、postUserWithHttpInfoを使うとよいです。
httpステータスは、postUserWithHttpInfo.statusCode、レスポンスの中身は、postUserWithHttpInfo.bodyなどとレスポンス内容を取得できます。
HttpStatusクラスを使って、

ResponseUserPost user = await api.postUserWithHttpInfo('');
if(user.statusCode == HttpStatus.unauthorized) {
    // 認証に失敗したらログイン画面へ遷移する
}

などと言った処理も書くことができます。

おまけ

他にもメソッドやら、定数が自動生成されていて、いろいろ使い方ができそうなので見てみるとよいかと思います。初心者でも比較的読みやすいかと思います。

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1