技術的なやつ

技術的なやつ

8.1 Web API: The Good Parts 1章~2章

Web API: The Good Parts

Web API: The Good Parts

年明けから、この本を読んでいる。もう辞めるけど、仕事でAPI触っていたのと、個人的に作りたいものにAPIが必要になりそうなので。
APIの設計についての200ページ位の本。サクッと1月中旬までに読みたい(できるかな)。
読んでて気になったとことか雑多に纏めていこうかなーと思う。

第1章 Web APIとは何か

Web APIの定義

URIにアクセスすることで、情報を(主に)JSONで取得できるようなもの。つまり、サーバとクライアントとの橋渡しとなる部分で、ブラウザを通して人間が読むためのものではなく、第三者がプログラムを通して利用することを前提としている。

Web APIの公開メリット

APIを公開することは、第三者のサービスが自分のサービスの情報を利用できるようになるということで、一見利点が無いように見える。だが、良いAPIを公開することで結果的に自分のサービスの知名度を上げることが出来、第三者のサービスは自分のAPIを通しているので、事実的に自分の掌の上にあるも同然であり、メリットがデメリットを上回る。また、自分のサービスが保持する情報に価値があるなら、どちらにせよ第三者はWebスクレイピングで何とかして情報を得ようとするだろう。

APIの対象開発者を考える

対象開発者にはLSUDs(large set of unknown developers)とSSKDs(small set of known developer)がある。LSUDsは未知のたくさんの開発者、SSKDsは既知の小数の開発者という意味である。対象者によってAPIの設計は変える必要があるだろう。

第2章 エンドポイントの設計とリクエストの形式

言葉の定義

エンドポイントは、APIURIのこと。

URI設計

覚えやすく、どんな機能を持つURIなのかひと目で分かるものが良い
具体的には、以下の通り。

短く入力しやすい

http://api.example.com/service/api/search より http://api.example.com/search が良い。

人間が読んで理解できる

http://api.example.com/s より http://api.example.com/search が良い。

大文字小文字が混在していない

getUserNameとか。こういう名前を付けなければならない状況が発生するのは設計ミス。

改造しやすい(Hackableである)

http://api.example.com/items/123456 というURIは、ID:123456のアイテムに関するURIで、番号を変えれば他のアイテム情報にもアクセスできることが容易に想像可能。

サーバ側のアーキテクチャが反映されていない

APIの形式をデータベースのテーブル構成等に合わせる必要はない。また、どんな言語を利用しているかをURIに反映させる必要もない。逆に、そのような情報を間接的に公開してしまうことで、攻撃者にとって有益な情報を与えてしまうことになる。

ルールが統一されている

http://api.example.com/items/123456http://api.example.com/friends?id=123456 のようなURIを混在させない

HTTPメソッドの利用

HTTPメソッドにはGET・POSTの他にも、PUT・DELETE等も存在する。エンドポイントは一箇所にして、メソッドによって操作を変更するのがHTTPの理念に沿っている。

メソッド 説明
GET リソースの取得
POST リソースの新規登録
PUT 既存リソースの更新
DELETE リソースの削除
PATCH リソースの一部変更
HEAD リソースのメタ情報の取得

たとえば、http://api.example.com/users というエンドポイントに対して、GETメソッドでアクセスした場合はユーザーの一覧取得、POSTメソッドでアクセスした場合はユーザーの新規登録を行うと良い。

検索のクエリパラメータ

タイムライン一覧の検索等では、データの全てを取得することは考えにくく、取得数の制限(limit)とどこから取得するかという情報が必要になる。
「どこから取得するか」に関しては、相対位置(offset)と絶対位置(since_id)の2つが考えられる。
相対位置では、最新情報からいくつかの情報を省いて取得する。これは、更新頻度の高いテーブルには適さない。また、データ数が増えるに連れて線形的に動作速度が落ちる。
絶対位置では、クライアントが最後に取得した情報のIDを利用する。

自分の情報へのエイリアス

自分の情報を取得するのに、http://api.example.com/users/123456 というURIの他に、http://api.example.com/users/self 等のURIを利用できるようにした方が良い。

OAuth2.0の利用

OAuth2.0は、標準化された、広く認知された仕組み。あるサービスのユーザー情報を第三者サービスに、情報源サービスのパスワードを第三者サービスに送信すること無く流すことが可能。

SSKDsに対するAPIデザイン

第三者サービスがホーム画面を用意することが分かっているなら、そこに必要な情報(ユーザー情報・タイムライン等)を全て一度に返すAPIを用意すべき。
1スクリーン1APIコール、1セーブ1APIコール

HATEOAS と REST LEVEL3 API

REST LEVEL
  • REST LEVEL0…HTTPを使っている
  • REST LEVEL1…リソースの概念の導入(エンドポイントの/usersとか/itemsとか)
  • REST LEVEL2…HTTPの動詞の導入(HTTPメソッドAPIへの利用)
  • REST LEVEL3…HATEOAS概念の導入
HATEOAS

HATEOAS(hypermedia as the engine of application state)とは、APIのレスポンスに次に想定されるアクセスAPIURIを含めること。
たとえば、friends情報を取得した時に、あるフレンドの情報を得るためのURIおよびその意味を、

"friends": {
	{ "name": "Jack",
	"link" : {
		"uri" : "http://api.example.com/users/
		"rel" : "user/detail"
	},
  ...
}

の形式でレスポンスに含める。

まとめ

  • URIは短く簡潔に。ただし、意味が分からないレベルまで短くしない。
  • URIは対象の名詞(複数形)にして、HTTPメソッドで動詞を表すと良い。
  • 検索で「どこから取得するか」については、相対位置と絶対位置の2通りが考えられる。
  • 認証ユーザーに対するアクセスにはself等のエイリアスを用いることが可能なようにする。
  • SSKDsには、場合によっては複数情報を纏めて返すAPIを用意する必要がある。
  • REST LEVEL3 を目指したい。

(重大っぽい)誤植?

この本、割と誤植が多いので、重大っぽい誤植だけ挙げておく。初版第1刷です。

P39

「mediumがmediaの複数形」ではなく、「mediaがmediumの複数形」。

図2-6 OAuthの基本的な仕組み

3番と4番の矢印が逆。

感想

HATEOASについては、まだ思想が広まっていないのでこの先どうなるか分からない、としか触れられていないが、概念を取り入れたAPI設計にすべきだと思う。
なぜなら、エンドポイントの変更があった場合でも、第三者サービスに改修の必要が生じないからだ。また、第三者サービスのプログラムに具体的なURIを含める必要性が少なくなり、第三者にとって扱いやすいAPIとなる。
デメリットとしては、APIのレスポンスが煩雑になるということが挙げられるが、JSONの設計を上手く行えばマシになるのでは無いかと思う。