Skip to content

Instantly share code, notes, and snippets.

@Altech
Created November 7, 2017 00:48
Show Gist options
  • Save Altech/d944edfb32231537a05b574e2f550aec to your computer and use it in GitHub Desktop.
Save Altech/d944edfb32231537a05b574e2f550aec to your computer and use it in GitHub Desktop.
API v2 - protocol and implementation

API Protocol

v1 との違い

一番大きなところでは、以下のように設計の考え方が異なる。

  • v1 : 1 screen, 1 API call. 画面に必要なものを全て返すエンドポイントを作っていく設計。
  • v2 : リソースごとにエンドポイントを作っていく設計(RESTful API)。

RESTful に API を作っていくことの大きなメリットは、アプリの画面と API の結合性が低くなり、生産性が上がること。 具体的には、Web エンジニアがアプリの画面の詳細まで知らなくても設計ができる、iOS と Android で実装状況が異なる場合にも API の中で条件分岐が必要ない、といったことが挙げられる。

これは別の見方をすると、あるエンドポイントが様々な画面で使われるということになる。 画面によって必要な情報の多寡は異なるので、スケールするように、v2 ではデフォルトではリソースの id のみを返し、それ以外の情報は全てホワイトリストで取得する。

レスポンス形式

v1 と異なり、{ "data": { ... }} と言った data によるラッピングは行わない。 これは、HTTP ではヘッダーが用意されており、メタデータはここに入れることができるため。

詳細エンドポイントの例

オブジェクトが返る。

# GET /api/v2/users/1
{ "id": 1 }

一覧エンドポイントの例

オブジェクトの配列が返る。

# GET /api/v2/users
[{ "id": 1 }, { "id": 2 }, ...]

エラー

HTTPステータスは通常の使い方に従う。 より詳細なエラー情報として、messageerror_code をボディに含める。

{ message: "...", error_code: 100 }

クエリパラメータ

フィールドの取得 : fields

例えば、ユーザー情報を取得する場合、fields=name のように指定すると id に加えて名前が返る。

複数指定する場合、カンマ区切りで fileds=name,facebook_uid とするか、角括弧を使って fields[]=name&fields[]=facebook_uid とすることで可能。

アソシエーションの取得 : include

例えば、ユーザーの画像のURLを一緒に取得する場合、include=avatar&fields=avatar.url のように指定するとアバターのURLも同時に取得できる。この場合、avatar アソシエーションのフィールド url を avatar.url といった形で取得している。

ネストしたアソシエーション

例えば会社の社員インタビュー一覧のエンドポイント GET /companies/:id/employee_interviews があって、そこでインタビュータイトルと同時にユーザーの名前とアバターURLを取得したい場合、パラメータは、次のようになる。

include=user,user.avatar&fields=title,user.name,user.avatar.url

デバッグパラメータ

事前にどんなパラメータがあるのかこのままでは仕様書が無い限り分からないので、debug パラメータを用意してある。これを true / t に設定すると、全フィールドと一段階までのアソシエーションが全て返る。production 環境では利用できないので注意。

ソート

ソートはデフォルトで一覧エンドポイントのテーブルのカラムに対して行えるようになっている。 例えば、col1, col2 というカラムを持つテーブルであれば、+col1, -col1, +col2, -col2 をデフォルトで受け付ける。

具体例として、ユーザーを名前を昇順で取得したい場合、sort=+name_ja といった形で指定できる。ユーザーを facebook_uid の降順で取得したい場合、sort=-facebook_uid といった形で指定できる。カンマで区切ることで複数のカラムでのソートも可能。

controller 側で sort_param を使うことで、対象テーブルのカラム以外でのソートを定義することも可能。 例えば、 companies#employees では sort=-score によって Wantedly スコアの降順でのソートを提供している。大きく、昇順なのか降順なのかは常にあるので、+- を先頭につけておくのがベター。

ページング

一覧エンドポイントで per_page , page パラメータを指定することでページングができる。 デフォルトで以下の情報がレスポンスヘッダーに入る。

X-List-CurrentPage: 4

また、page_count パラメータを true に設定することで、次の情報も返る。 バックエンドでは COUNT クエリが余分に一個走るため、デフォルトの挙動にはなっていない。

X-List-TotalCount: 123
X-List-NumPages: 1
X-List-IsFisrtPage: true
X-List-IsLastPage: false

フィルタ

一覧系のエンドポイントでは様々なパラメータでフィルタリングすることが考えられるので、既に挙げたパラメータ以外の任意のパラメータが実装される。 どういう利用可能なパラメータについては、後述するように controller の引数に明示される。

関連資料

おおよそ以下の資料に書いてあるような方針で設計している。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment