18
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

SwiftのWebAPIのInterfaceのコードを自動生成する

18
Posted at

はじめに

構造を定義したJSONを安全に扱うSwiftコードを自動生成する の続きです。
今度はWebAPI用のコードをお手軽に生成することを考えてみます。

任意のHTTP Requestをお手軽に実行する優れたLibraryは本当にたくさんあって、どれにするか迷うくらいです。
ただ、通常のサービスや自分で作っているWebAPIの場合はInterfaceが事前に決まっているにもかかわらず、
リクエストパラメータやレスポンスデータを処理する部分は仕様書を睨みながらコードを書き起こす必要があります。
可能ならばこの辺を省力化したり、型安全の恩恵を受けたいと思うところです。

WebAPI Interfaceの自動生成

Qiita API V2 の一部を例にやってみます。
https://qiita.com/api/v2/docs#get-apiv2items の辺りです。

APIの定義

Qiita API の中から以下の4つを取り出して定義してみます。

  • GET /api/v2/items
  • POST /api/v2/items
  • GET /api/v2/items/:id
  • PATCH /api/v2/items/:id

定義はこんな感じになります。

qiita_api.yml
api_prefix: QiitaAPI
entity_prefix: Qiita

api:
  ListItem:
    get: items
    params:
      page?: Int
      per_page?: Int
    response: [Item]

  GetItem:
    get: items/{id}
    response: Item

  PostItem:
    post: items
    body:
      body: String
      coediting: Bool
      gist?: Bool
      private: Bool
      tags: [Tag]
      title: String
      tweet?: Bool

  PatchItem:
    patch: items/{id}
    body:
      body: String
      coediting: Bool
      private: Bool
      tags: [Tag]
      title: String

entity:
  Tag:
    name: String
    versions: [String]

  Item:
    body: String
    coediting: Bool
    created_at: String
    id: String
    private?: Bool
    tags: [Tag]
    title: String
    updated_at: String
    url: String
    user: User

  User:
    description?: String
    facebook_id?: String
    followees_count: Int
    followers_count: Int
    github_login_name?: String
    id: String
    items_count: Int
    linkedin_id?: String
    location?: String
    name?: String
    organization?: String
    profile_image_url?: String
    twitter_screen_name?: String
    website_url?: String

Swiftコードの生成

こんな感じで生成します。

git clone https://github.com/mokemokechicken/ObjectJsonMapperGenerator.git
cd ObjectJsonMapperGenerator
ruby bin/make_ojm.rb -l swift -t api -c qiita_api.yml > qiita_api.swift 

今のところ出力結果はこうなります。
https://gist.github.com/mokemokechicken/ec01464d4e48b04ebc15

使ってみる

生成したコードをプロジェクトに追加しておくと、以下の様な感じで使うことができます。

main.swift
import Foundation

private let config = QiitaAPIConfig(baseURL: NSURL(string: "http://qiita.com/api/v2/")!)
private let apiFactory = QiitaAPIFactory(config: config)

apiFactory.createListItem().setup(perPage: 3).call { res, items in
    items?.map { item in
        println("\(item.user.id): \(item.title)")
    }
    return
}

CFRunLoopRun()

実行結果

mikoski01: Composerを使ってCakePHP環境を楽々構築!(Windows)
mutz0623: CentOSのデフォルトのApacheで、デフォルトのRubyでmod_mrubyをビルド
gam0022: Rails4のアプリをHerokuで動かす

さいごに

こういう風にやると、YAMLで書いた定義がAPI仕様書みたいになるのでなかなか便利に使えますね。
YAMLで記述するとaliasが使える(ある部分を&で定義して、*<<: *で参照できる)のですが、
これは意外と使える!と思っていたりします(Railsみていて最近気がついた)。

まあ、まだまだ課題はありますが、色々なAPIで試しつつ潰していきたいと思います。
ファイルアップロード、ダウンロードのプログレスバーとか。。。まあ、それくらいなら書いても大したことないけど。。

後はこれを使うModelを似たような感じでひな形が作れれば良いんだけどなぁと思っていますが、
Modelはひな形をベースにしてどんどんコードを追加していく感じになるので、
コード生成という観点ではどういうアプローチがいいのか難しいところです。

ある程度Swift版ができたらJava版も作りたいです。
コードジェネレーターを作るのも少しずつ慣れてきました。何事も練習ですね。
それにしてもコードを全部書き直したい病がしばしば発症するなー

18
18
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
18
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?