Restful-web-api-memo-15
Chapter 11. HTTP for APIs
- Web APIの技術的スタック
- ハイパーメディア
- 次は何?に答える
- HTTP
- リソースとはどのようにしてやりとりするのか?に答える
- URL
- リソースはどこにあるのか?に答える
- ハイパーメディア
HTTP仕様
- RFC2616
- 41のレスポンスコードを定義
- プロトコルセマンティクスの基本セットを表現する
- 400
- 不正なデータが送りつけられてきた場合
- 問題点をentity-bodyに示す
- 付録A参照
- 47のリクエスト / レスポンスヘッダを定義
- プロトコルセマンティクスの基本セットを提供する
- 付録B参照
- 表現の選択
- 一つのリソースは多くの表現をもつ
- 表現は異なるフォーマットをもつ
- コンテントネゴシエーション
- Accept-*のセットが提供されている
- Accept
- media-typeの選択
- Accept-Language
- 言語の選択
- 対応する表現がない場合、406(Not Acceptable)を返す
- プロファイルネゴシエーション
- media-typeがprofileパラメータを持つ場合に利用可能
- コンテントネゴシエーションと合わせて使用する
- ハイパーメディアメニュー
- 利用可能な表現の一覧を返し、その中からクライアントに選択させる
- 300(multiple Choices)を返す
- entity-bodyに選択可能なリンクを提示する
- htmlのaタグ、linkタグはハイパーメディアメニューきのうを持つ
- type属性
- media-typeを指定する
- hreflang
- 言語を指定する
- type属性
- 正規化URL
- リソースが一つ以上のURLを持つ場合、代表のURLを明示すること
- 以下のいずれかを使用
- Content-Location
- canonicalリレーション
- キャッシュ(Cache-Control)
- リクエスト
- キャッシュを使うかどうかの指示
- レスポンス
- 前回のリクエストから変更があったかどうかを伝える
- API実装を変更する場合、マイグレーションのために適切にmax-ageを設定すべき
- リクエスト
- Conditional Request * リソース状態が変更する場合、適切にmax-ageを決定することは難しい * Last-Modified * レスポンスで最終更新日時を返す * 次回リクエストでIf-Modified-Sinceヘッダに埋め込む * リソース状態が変更していない場合、304(Not Modified)を返す * 動的、静的コンテンツにかかわらずサーバーリソースを節約できる * 次回リクエストのために保存しておく必要がある * ETag * リソース状態が変更した時のみに変更される文字列 * リソースをハッシュ化して生成 * Last-Mofifiedのように、別途保存しておく必要がなくなる * 次回リクエストでIf-None-Matchに、ETagの文字列を指定する * リソース状態に変更がなければ304(Not Modified)を返す
- LBYL(Look Before You Leap) Request
- entity-bodyのないPUTリクエストを送る
- PUTが受け入れ可能な場合、100(Continue)を返す
- 改めて、entity-body付きでPUTリクエストを送る
- PUTが棄却された場合、417(Expection Failed)が返される
- 圧縮
- リクエストヘッダにAccept-Encodingを含める
- たいていgzip
- サーバーが圧縮アルゴリズムをサポートしていれば、圧縮
- レスポンスヘッダに同じAccept-Encodingを含める
- リクエストヘッダにAccept-Encodingを含める
- Partial GET
- 表現のサブセットを取得する方法
- 主にダウンロードを再開する目的でもちいられる
- リクエストヘッダに開始位置をRangeに指定
- 単位はkB
- レスポンスコードは206(Partial Content)
- レスポンスヘッダにContent-Rangeを含める
- コレクションの一部の取得に使えそうだが、非標準
- 自身のプロトコルセマンティクスを検討すべき
- prevやnextなどのリンクリレーション
- HTTPパイプライン
- クライアントは一度に複数のリクエストを送る
- サーバーは受け取った順にレスポンスを返す
- GETのみでパイプライン化が望ましい
- ほかのメソッドとの組み合わせは、途中で切断されてもロールバックできないため
- Web APIとは相性が悪い
- たいていAPIは、ワークフローとなるため
- Lost Update問題点をの回避
- 不安定なメソッド(PUT/PATCH)を同時に使われると、後勝ちとなる
- 先勝ちにしたければConditional Requestを使う
- Last-Modified
- If-Unmodifid-Since
- ETag
- If-None-Match
- Last-Modified
- 変更されていれば、412(Precondition Failed)が返される
- 不安定なメソッドには、常にConditional Requestが望ましい
- 利用されていなければ、428(Precondition Required)を返す姿勢で
HTTP認証
- Basic認証
- RFC2617
- ユーザー名/パスワードの組で認証
- あまりセキュアではない
- クレデンシャルはBase64エンコードされるだけ
- TLSに乗せれば、盗聴を防げるので、多少セキュアになる
- Digest認証
- RFC2617
- OAuth 1.0
- RFC5849
- クライアントごとに別々のクレデンシャルを与える
- 利用者は、トークンクレデンシャルを利用停止にすることで、スパム被害を最小化できる
- OAuthプロバイダは、クライアントクレデンシャル(consumer_key)を停止することで、スパム被害を最小化できる
- OAuth 2.0
- RFC6749
- 4つのアクセストークン取得プロセス
- Authrization Code
- OAuth 1.0の方法
- Implicit Gant
- Resource Owner Password Credential
- モバイルクライアント向け
- Client Credentials
- Authrization Code
HTTP拡張
- WebDav
- HTTP/2
- CoAP
- PATCHメソッド
- RFC5789
- 安全ではないがベキ等でない
- 差分更新を可能とする
- パッチフォーマット
- application/json-patch
- RFC6902
- application/xml-patch+xml
- RFC5261
- application/json-patch
- LINK/UNLINKメソッド
- RFC2616(破棄)
- 使い道が見出せなかったため
- 安全ではないが冪等
- 2つのリソースかんを接続(切断) するメソッド
- リンク先は、LINKヘッダで指定する
- RFC2616(破棄)
WebDav
- RFC4918
- HTTPベースのファイルシステム
- 利用例
- MS SharePoint
- Subversion
- メソッド
- MKCOL
- コレクションの新規作成
- PROPATCH/PROPFIND
- リソースにキーワードをつけることで、検索しやすくする
- LOCK/UNZlOCK
- リソースのロック
- 同時アクセスを防ぐ目的
- すでにロックされてれば、408(Conflict)を返す
- 423(Locked)も定義されてるが利用は推奨されていない模様
- MOVE/COPY
- リソースの移動またはコピー
- 目的地は、Destinationヘッダで指定する
- MKCOL
Http/2
- SPDYベースにした進化版
- ヘッダ圧縮
- 同時リクエスト発行