Web API: The Good Parts
1章 Web APIとは何か
Web API
HTTPプロトコルを利用してネットワーク越しに呼び出すAPI
Amazon Product Advertising APIの歴史は古い (2003年公開)
AmazonもTwitterもどちらのケースも、いわば自分たちが資金を投じて作ったシステム、集めたデータを無料で公開しているようなものですから、近視眼的に見れば損をしているようにも見えます。しかし新しいシステム、サービスを公開する力を持った開発者にAPIを公開することで、彼らがサービスに付加価値を与えてくれ、コアとなる自分たちのサービスがより発展する力をもらうことができているわけです。
API利用前提のサービス
何をAPIとして提供すべきか
コアサービス
美しく設計する
API設計の原則
仕様が決まっているものに関しては仕様に従う
仕様が存在していないものに関してはデファクトスタンダードに従う
対象となる開発者の数とAPIの設計思想
LSUDs
SSKDs
2章 エンドポイントの設計とリクエストの形式
ごく簡単なSNSサービスを例に
SQL (DBのテーブル) をラップしたようなAPIにしない
ユースケースを考える
原則
覚えやすく、どんな機能を持つURIなのかがひと目でわかる
サーバ側のアーキテクチャが反映されていないURIにする
cgi-bin
.php
HTTPメソッドとエンドポイント
HTML5ではフォームでPUTやDELETEも使える仕様が盛り込まれていたが結局削除された GET, POSTしかできない場合どうする?
X-HTTP-Method-Overrideヘッダ
_method パラメータ
一覧を取得するAPIのエンドポイントの形式はあまり統一されていない
単語をつなげるときはハイフン
実情としてはあまり統一されていない
クエリパラメータ
取得数
ページング
相対位置
絶対位置
offset, limitは遅いという話題
utgwkk.icon 3年ぐらい前に通った
認証
OAuth
自分の情報へのエイリアス
me
self
user
APIを提供するホスト名・エンドポイントの共通部分
example.com -> api.example.com
/v1/
SSKDs向けのAPI
LSUDs向けのAPIだけでホーム画面を作ろうとすると何度もAPIを叩くことになる
1スクリーン1APIコール、1セーブ1APIコール
hypermedia as the engine of application state
LEVEL
0: HTTPを使ってる
1: リソースの概念の導入
2: HTTPの動詞の導入
3: HATEOASの導入
次に行う行動、取得するデータ等のURIをリンクとして含める
メディアタイプを変える
application/vnd.companyname.user.detail.v1+json
URIを改造しやすくする必要がなくなる
3章 レスポンスデータの設計
デフォルトJSON、需要があればXML
データフォーマットの指定方法
クエリパラメータ
拡張子
Acceptヘッダ
utgwkk.icon 現代では対応しなくてよさそう
データの内部構造
APIのアクセス回数がなるべく減るようにする
user_idのリストだけ返すと、リストの個数ぶんだけAPIリクエストする必要がある
バックエンドでJOINしてまるっと返しましょう的な
レスポンスの内容をユーザーが選べるようにする
fields=name,age
レスポンスグループ (Small, Medium, Large)
エンベロープは必要か
いらない、HTTPの仕様に則るべき
(JSONPのときは必要)
データはフラットにすべきか
なるべくフラットにすべきだけど階層化したほうが絶対によい場合は階層化もあり
場合による
配列とフォーマット
オブジェクトで包むべき
JSONインジェクション対策
件数、続きがあるかどうか
hasNext
HATEOAS的な
各データのフォーマット
性別
sex
gender
日付
大きな整数
JavaScriptのNumberは64bit浮動小数
id_str
レスポンスデータの設計
utgwkk.icon 型があると便利なのじゃ、みたいな話と思った
エラー
HTTPステータスコード
失敗したときに200番台を返さない
詳細をクライアントに返す
X-Error-Message的なヘッダ
レスポンスボディに入れる
何を入れるべきか
エラーコードがあると便利?
HTMLが返るのを防ぐ
クライアントはJSONを期待している
メンテナンス
503を返す
Retry-After
意図的に不正確な情報を返したい
セキュリティ
ブロックされた側に404を返す
4章 HTTPの仕様を最大限利用する
不本意に独自仕様を入れない
ステータスコードのセマンティクスに従う
エラーで200を返さない!!!!!
utgwkk.icon 300が実際に返る例あまり見たことがない
304
キャッシュ
期限切れモデル
Expires
Cache-Control: max-age
Dateヘッダ
ExpiresとCache-Controlを同時に使ったらCache-Controlが優先される
検証モデル
キャッシュが有効か検証する
有効なら304
ETag
ApacheのETag生成方法
ディスク上のノード情報を使わないようにしましょう
If-None-Match
Last-Modified
If-Modified-Since
強い検証と弱い検証
強い: データが1バイトも違わない
弱い: 意味合いは変化してない
Heuristic Expiration
クライアント側が独自の判断でアクセス回数を減らす
キャッシュさせたくない
Cache-Control: no-cache
「キャッシュしてはいけない」ではない
Vary
Cache-Control
いろいろある
stale-while-revalidate
有効期限が切れてもこの秒数のうちはキャッシュから返してよい
裏でキャッシュの検証を行う
stale-if-error
オリジンサーバへのアクセスができなかったときに新鮮でないキャッシュを返してよい
メディアタイプ
Content-Typeを正しく指定すべき
自分でメディアタイプを定義する
vnd.
prs.
x.
RSSとか
GitHubの場合
X-GitHub-Media-Type: github.v3
セキュリティ
Content Sniffing
Acceptヘッダの読み方
Same Origin Policy
CORS
プリフライトリクエスト
utgwkk.icon $.ajax をaxiosに書き換えたらなんかOPTIONリクエスト飛んでるけどなんで!!! ってなってた思い出がある
独自のHTTPヘッダ
X- 接頭辞を付けるべきかどうか
付けなくてもよいのではという流れもある
いずれにせよ付けるか付けないかは統一されているべき
5章 設計変更をしやすいWeb APIを作る
重要性
LSUDs向け
SSKDs向け
APIをバージョンで管理
v1よりv2のほうが新しい
バージョンの付け方
メジャーバージョンだけにする
クエリ文字列に入れる
メディアタイプ
バージョンを変える際の指針
どうしても後方互換性を保つのが難しい場合のみにとどめる
常に最新版を返すエイリアス
いらない
提供終了
Twitter API 1.1の提供と1.0の廃止
ブラックアウトテスト
一時的に1.0へのアクセスができないようにする
あらかじめ提供終了時の仕様を盛り込んでおく
HTTP 410
強制アップデート
利用規約にサポート期限を明記する
DoubleClick
オーケストレーション層
OSFAアプローチ
洋服のフリーサイズみたいなイメージ
Netflix社の事例
Client Adapter Code
共通のサーバAPIが返すレスポンスを変換
6章 堅牢なWeb APIを作る
安全
情報の不正入手
MITM
HTTPSを使う
ブラウザからアクセスするAPI
XSS
Content Sniffing
X-Content-Type-Options: nosniff
JSON文字列のエスケープ
X-Requested-With: XMLHttpRequest
UTF-7攻撃
XSRF
utgwkk.icon CSRFのことか
ぼくはまちちゃん!
CSRFトークン
X-Requested-Withのチェック
JSONハイジャック
scriptタグとして読み込む
VBScript
Content-Typeを指定する
X-Content-Type-Options: nosniff
配列ではなくオブジェクトを返す
JSONファイルの先頭に無限ループ
Facebook
悪意あるアクセスへの対策を考える
艦これ
パラメータの改竄
マイナスのパラメータを送信する
リクエストの再送信
アプリ内課金
HTTPヘッダ
X-Content-Type-Options
X-XSS-Protection
X-Frame-Options
Content-Security-Policy
いわゆるCSP
Strict-Transport-Security
HSTS
Public-Key-Pins
Set-Cookie
Secure
HttpOnly
utgwkk.icon SameSiteはこの記事 (2015年ぐらい) まだなかったか
大量アクセス
ユーザーごとのアクセス制限
レートリミット
ウィンドウ (15分とか)
progressive rate limit
utgwkk.icon Facebook APIはCPU時間を使ってた気がする、あとで調べます
制限を超えた
429
Retry-After
ユーザーに伝える
レートリミットを知る用のAPI
HTTPレスポンス
レートリミットの実装
Redisとかを使う
付録A Web APIを公開する際にできること
APIドキュメント
サンドボックスAPI
APIコンソール
SDK
付録B Web APIチェックリスト
utgwkk.icon 網羅的でよさそう
感想コーナー
utgwkk.icon Twitter APIで遊びまくるみたいな事例あまり聞かなくなりましたね
utgwkk.icon そういえばAjaxやXMLHttpRequestが文字通りにXMLを返していた時代はどうやってレスポンスボディをパースしていたのだろうか、詳しい人いたら教えてください!
utgwkk.icon ブロックされたときに404を返しても未ログインなら見れるみたいな場合もありそう。ログイン (認証) 必須にしたらそうでもないか
utgwkk.icon オンラインゲームは無限に考えることがありそう
https://gyazo.com/53b6509db1c8db0c88f371318a408202