RESTful Web APIs 読書メモ(9)
Chapter 9. The Design Procedure
- API設計とは、プロトコルセマンティクスとアプリケーションセマンティクスを設計すること
最も単純な手順
- 表現として使用するmedia-typeを選択する
- プロトコルセマンティクスとアプリケーションセマンティクスを選択することでもある
- application/json
- 今日、幅広く使われている形式
- fiat standardとなるので再利用出来ない
- Profileを用意する
詳細な手順
- クライアントがAPIを通して、get/putする情報の素片をリストアップする
- 情報の素片は階層構造をもったsemantic descriptor (リソースの表現) となる
- この時点では、用語のブレは気にしない(first-name, first_name)
- 語彙は、データベーススキーマやオブジェクトモデルからはもってこないこと
- クライアントコードがサーバーサイドに依存してしまうため
- media-type在りきでデータ構造を決定しないこと
- 6. まで我慢する
- IANA登録済みのlink relationと重複させないこと
- ページネーション
- first, next, current
- next-archive, prev-archive (RFC5005)
- メッセージスレッド
- replies (RFC4685)
- リソース状態の履歴管理(RFC5829)
- latest-version
- successor-version
- predecessor-version
- working-copy
- working-copy-of
- リソース状態の編集
- edit
- edit-media
- ページネーション
- 情報の素片は階層構造をもったsemantic descriptor (リソースの表現) となる
- APIの状態遷移図を描く
- 一つの状態に一つの表現を割り当てる
- 一つの状態遷移が一つの矢印となる
- httpメソッドはまだ割り当てない
- 冪等性と安全性は考えておくべき
- link relationが発見されるかもしれない
- 構造化された内と外との間のリンク
- 用語がアプリケーション状態の変化をもたらすのであれば、その用語はリレーション
- 拡張リンクリレーション
- http://example.com/maze#exit
- profile取り込むことなく使用可能
- 階層構造が変化するかもしれない
- 状態間は、グループ化されたdescriptor (ValueObject)が行き来する
- 状態遷移におけるトップレベル表現を設ける
- ほかの状態へは、ハイパーメディアコントロールを通して
- semantic descriptorとlink relationが満足するまで、1, 2を繰り返す
- 用語のブレは解消しておくこと
- 用語が既知のprofileに存在するのなら、それに置き換える
- IANAに登録されたリレーション
- schema.orgに登録された用語
- alps.ioに登録された用語
- ドメイン特化フォーマットで使用される用語、などなど
- 既知の語彙は間違った理解を減らせる
- profileの再利用は、書くべきドキュメント量を減らせる
- profileの再利用は、ライブラリの再利用を促せる
- たいていはprofileを使用せず、media-typeに結びつけてしまっている
- 一つのAPIに対して複数のmedia-typeを独自定義せず、複数のprofileを利用する
- 金融、法務関係のprofileは、未整備のため再利用は難しい
- 用語と状態遷移図が満足するまで、1 - 3を繰り返す
- プロトコルセマンティクスとアプリケーションセマンティクスに適合するmedia-typeを選択する
- 運が良ければ、ドメイン特化フォーマットが見つかるかもしれない
- 独自定義する場合、標準的な命名規則に従う
- application/vnd.(org name).(base type)
- (例) application/vnd.hoge.maze+xml
- より汎用的な利用を考えているのならIANAにmedia-typeを登録する
- RFC6838の4, 5節の手順に従う
- JSONベースならRFC4627を目を通すべし
- XMLベースならRFC3023に目を通すべし
- 可能な限り、ハイパーメディアフォーマットを選択する
- コレクションパターン
- Collection+JSON
- AtomPub
- OData
- 有向グラフ構造
- HTML
- HAL
- Siren
- 読み取り専用API
- HTML
- HAL
- JSON-LD
- 安全でないメソッドを使用する場合
- Hydra
- Collection+JSON
- 未知の用語に対して、profileを用意する
- machine-readable フォーマット
- Alps
- JSON-LD
- XMDPベースのwebページ
- Alps
- profileでlink relationを定義した場合、IANAのものよりも優先される
- 意図的にやるべきではない
- machine-readable フォーマット
- 状態遷移図を満たすサーバー実装を書く
- トップのURLを公開する
- 状態遷移図のゲートウェイをトップURLとする
- Profileを配置する
- 自サイト
- alps.io
- APIの要約
- 利用例
- サンプルコード
- 認証手順
- Well known URIs Registry (RFC5785)
- CoRE Link Formatの場合
- /.well-knoen/coreに問い合わせ
- 相対URLは、IANAレジストリに登録
- ほかリソースのハイパーメディアリンクの一覧を取得できる
- ホストメタデータの取得
- /.well-known/host-meta.json
- または、/.well-known/host-meta
- well known URIは、media-typeに関連付けられる
- CoRE Link Formatの場合
バージョニング
- 前提
- 第一にAPIのセマンティクスをhuman-readableドキュメントやハイパーメディアドキュメントの外に置くこと * 変更に強くなる
- 既存のリソース定義を変更するのではなく、新しいリソースや状態遷移を追加するに留める
- URLに付与
-
のような感じ
- media-typeに付与
- コンテントネゴシエーションとして指定
- Accept: application/vnd.hoge?version=2
- media-typeはAPIではないのでやめといた方がいい
- Accept: application/vnd.hoge?version=2
- コンテントネゴシエーションとして指定
- profileを使う
- 破壊的変更はhuman-readableに記述
- 非破壊変更はmachine-readableなハイパーメディアで記述
- リソーススキーマの変更
- 後方互換性を保ちたいなら、異なるURIを持つ新たなリソースを定義する
古いAPIの止め方
- deplecatedをマークし、公式チャンネルでアナウンスする
- しばらくしたら、deplecatedマークしたバージョンはバグ修正しないことをアナウンスする
- 更に幾つか待って、停止の期限をアナウンスする
- 停止日が訪れたら、古いAPIのリクエストに対し、410(Gone)を返し、新しいAPIへのリンク先を案内する
既存のAPIをRESTfulにする場合
WSDL
- 非RESTful API
- サーバー実装と自動生成されるクライアント実装が密結合となる
- サーバー実装の変更をクライアントサイドに反映出来ない
既存のJSONベースAPIにハイパーメディアを追加する場合
- 名前(application descriptor) を変更しない
- media-typeを変更しない
- 安全でないリレーションを追加する場合、profileとしてHydraをもつJSON-LDがオススメ
既存のXMLベースのAPIにハイパーメディアを追加する場合
- XFirn, XLinkをハイパーメディアコントロールとして使用する
たとえわけの分からないレスポンスだったとしても
- media-typeやrelationがIANAに登録されている
- profileドキュメントへのリンクがあれば、なんとか解析はできる
- profileはmachine-readableに加えて、human-readableな情報があると尚よし