Skip to content

Instantly share code, notes, and snippets.

@Altech Altech/v2.md
Created Nov 7, 2017

Embed
What would you like to do?
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
You can’t perform that action at this time.