View
2.795
Download
7
Category
Preview:
Citation preview
RESTful API設計入門2015/1/30
自己紹介Speaker : {
“name”:”薬師寺 信勝”
“company”:”株式会社モンスター・ラボ”,
“department” : “音楽事業部”,
}
目次
• REFTfulとは
• RESTFul API設計ベストプラクティス
RESTFulとは
RESTFulとはRepresentational State Transfer(REST)
Webシステムのためのソフトウェアアーキテクチャ
RESTの重要な原則に従っているアーキテクチャをRESTFulと表現
原則• HTTPをベースとしたステートレスなクライアント/サーバプロトコル
• リソース操作の為のHTTPメソッドの定義
• リソースを一意に識別できる「汎用的な構文(URL)」を定義
• リソースリンクを使用
ステートレス
• リクエストは完全かつ独立したものにする
• サーバには状態を保持しない
• URLに処理に必要なデータをすべて表現
➡サーバ処理を軽くスケーラブルにできる
HTTPメソッド
GET リソースの取得
POST リソースの作成
PUT リソースの状態変更や更新
DELETE リソースの削除
HEAD メタ情報の取得。
OPTIONS URIで指定されたリソースでサポートされているHTTP(API)のリストを応答
リソースに対する操作をHTTPメソッドで表す
URL• URLはリソースの名前を示す
• Resource Oriented Architecture
• URLとリソースは1対1で関連付けられる
• 同じURLは必ず同じリソースを表す(べき等性)
• 名詞で構成
実行結果• 結果はHTTPコードで返す
• 200系 - 処理成功時
• 300系 - リソースの状態変更等
• 400系 - エラー(IFの指定が悪い)
• 500系 - エラー(サーバエラー)
ベストプラクティス
開発者視点
• REST原理主義になりすぎない
• 利用者の利便性が一番大事
リソースの抽出• Webに公開したいリソースを抽出する
• DBのテーブル構造をそのまま公開しない
• 名詞を探し名詞でURLを表現
• イベント自体をリソースとして抽出しない
• 承認/否認等。この場合は状態を管理するための情報としてリソースを抽出する。
• リソースはDBレコードだけはない。(計算結果、トランザクション等もある)
URL• 以下の形式を推奨
• http(s)://{REST APIであることを示すドメイン名(:ポート番号)}/{APIバージョン}/{リソースを識別するためのパス}(http://api.monstarlab.com/v1/hoge)
• http(s)://{ドメイン名(:ポート番号)}/{REST APIであることを示す値}/{APIバージョン}/{リソースを識別するためのパス} (http://monstarlab.com/api/v1/hoge)
• Webのリソースとして一意に識別できるURIを割り当てる
• 基本は”/コレクション/名詞”
• リソースの関係を表したい時に階層化する
• /members/1234/friends
• 階層は浅く保つ
• できるだけ/collection/identifier/collection以上深くすべきでない
• URLは浅く保ち複雑さはクリエリパラメータに
URL(例)• メンバーリスト
• /members
• メンバーID1234
• /members/1234
• グループ
• /groups
• /groups/1234
• /getGroup -> 動詞は使わない
バージョン• APIのバージョンをURLに付与する
• /v1/members
• URLに付与するとブラウザ等で呼び出しやすい
• 機能変更による振る舞いの変化に対応しやすい
• 市場に出ている古いバージョンのクライアントに対応できる
Partial response
• 利用者が指定したデータだけ返す。
• fieldsパラメータにカンマ区切りで指定
• /members/1234?fields=name,tel,mail
Pagenation• 応答件数を制御
• pageNumber, pageSize, sortパラメータで指定
• /members?pageNumber=1&pageSize=20&sort=id,name
• 応答には全レコード件数を含める。
• 省略時のデフォルト値を決めておく
検索• 全体検索
• サイト全体検索の場合は/searchで(分かりやすい)
• /search?name=sato
• /search?name=sato&age=20
• 部分検索はリソースURLのパラメータで
• /members?q=name
応答フォーマット• 基本的にはjsonを使用する
• フォーマットが複数ある場合はURLに拡張子をつけて指定
• /members/123.json
• /members/123.xml
• 応答データにはContent-Typeを付与。
• Content-Type: application/json
• Content-Type: application/xml
リソースフォーマット• フィールド名は「lower camel case」
• フィールドの先頭を小文字、単語の先頭は大文字(例:memberId)
• nullとブランクは区別
• 例:{ “dateOfBarth”: null, address: “”}
• 日時フォーマットは、ISO-8601の拡張形式を推奨
• yyyy-MM-dd 例:2015-01-01
• yyyy-MM-dd’T’HH:mm:ss.SSSZ 例:”2015-01-01T10:10:20.123+09:00”
• yyyy-MM-dd’T’HH:mm:ss.SSSZ(UTC) 例:”2015-01-01T10:10:20.123Z”
リンクフォーマットリンクは以下の形式を推奨 { "links" : [ { "rel" : "ownerMember", "href" : "http://example.com/api/v1/memebers/M000000001" } ] }
relとhrefを持ったlinksコレクションを複数持つ
エラーフォーマット• エラー時は同じフォーマットで応答する。
• クライアントが自己解決できるように詳細情報を含める。
• システムの脆弱性をさらすような事象は詳細情報を含めない。
• フォーマット例 { "code" : "e.ex.fw.7001", "message" : "Validation error occurred on item in the request body.", "details" : [ { "code" : "ExistInCodeList", "message" : "\"genderCode\" must exist in code list of CL_GENDER.", "target" : "genderCode" } ] }
• detailsには、パラメータエラーに対する各項目の詳細エラーを設定。
HTTPメソッド• リソースをどのように操作したいかを表す
GET リソースの取得
POST リソースの作成。URLを新規に生成する操作。
PUTリソースの状態変更や更新。URLに対応するデータが存在しない場合は生成、存在する場合は更新する。
DELETE リソースの削除
HEADメタ情報の取得。Getと同じ処理を行いヘッダ情報の
み取得。
OPTIONSURIで指定されたリソースでサポートされている
HTTP(API)のリストを応答
オペレーション例Resource
Post 作成
Get 読み込み
Put 更新
Delete 削除
/membersメンバーの新規
作成メンバー一覧の
読み込みメンバーの一括
更新メンバーの一括
削除
/members/1234
エラーメンバー
ID1234の読み込み
メンバーID1234の更新
メンバーID1234の削除
応答コードの選択• よく使用するもの
• 200,201,204
• 301,303,304
• 400,401,404,409,
• 500
• クライアント側が悪い時は400系、サーバが悪い時は500系
200系ステータスコード 説明 適用条件
200 OK 成功
リクエストが成功した結果として、レスポンスのエンティティボディに、リクエストに対応するリソースの情報を出力
する際に応答する。
201 CreatedPOSTメソッドを使用して、新しいリソースを作成した際に使用する。レスポンスのLocationヘッダに、
作成したリソースのURIを設定する。
204 No Content.リクエストが成功した結果として、レスポンスのエンティティボディに、リクエストに対応するリソー
スの情報を出力しない時に応答する。
300系ステータスコー
ド 説明
301 Moved Permanently 恒久的移動
303See Other
リクエストに対するレスポンスは異なるURIの下で発見でき、そのリソースをGETメソッドを使って検索することが望ましい。
304Not Modified
変更なし。リクエストされたリソースが指定された日付以降に更新されていない。クライアントが条件付きGETリクエストを実行し、アクセスは許可されたが、ドキュメントが更新されていない場合に
は、サーバはこのステータス・コードでレスポンスを行なうべきである。
400/500系ステータスコード
説明 適用条件
400 Bad Requestエンティティボディに指定されたJSONやXMLの形式不備を検出した場合や、JSONやXML又はリクエストパラメータに指定された入力値の不
備を検出した場合に応答する。
401 Unauthorized 認証が必要なURLに対して認証していない場合。
404 Not Found 指定されたURIに対応するリソースがシステム内に存在しない場合に応答する
409 Conflict排他エラーが発生した場合や業務エラーを検知した場合に応答する。 エンティティボディには矛盾の内容や矛盾を解決するために必要なエラ
ー内容を出力する必要がある。
500 Internal Server Error サーバ内で予期しないエラーが発生した場合や、正常稼働時には発生してはいけない状態を検知した場合に応答する。
認証/認可• 認可はOAuth2を使用する
• 独自形式はなるべく使わない
• メリット:クライアントは既存のライブラリが使える
• OAuth2は認可プロトコルであり、認証プロトコルではない
• 認証プロトコロルとしてはOpenIDが有名
• OAuth2は脆弱性があるのでセキュリティ対策をとること
煩いAPIにしない• 複数リクエストの実行を前提とした設計にしない
• 例: {
message { “senderId”: 1234 “title” : “ほげ” :
} } senderIdにidしか情報がないので、アプリで表示するには再度ユーザ情報を取得するAPIをリクエストしなくてはならない。 -> ユーザ情報も一緒に応答データとして含める
悩みが深い例• 「ユーザAが商品を購入」はどうする?
• ユーザAのアイテムリストに商品を追加する
• post: /v1/users/A/items
• 「ユーザAがB地点に到着」
• ユーザAの現在地をBに変更する
• put: /v1/users/A -> location: “B”
• 楽曲Aを音楽を再生する
• オーディオプレイヤー1の状態を楽曲Aの再生にする
• put: /v1/players/1 -> playStatus: { “status”: “play”, “music”: “ありのままで”}
• この場合は分かりやすく put:/v1/players/1/playでもよいかも。
悩みが深い例• 数値のIDはどうする?
• データを予想しやすいためランダム文字にしたほうがよい(UUID等)
• 予想されても問題ないならDBのプライマリキーとマッピング
• IDは意味のある値にしない(例:ログインID。ログインIDを後で変更できなくなる)
その他
参考• WEB API Design
• http://apigee.com/about/resources/ebooks/web-api-design
• RESTful Web アプリの設計レビューの話
• http://www.slideshare.net/t_wada/restful-web-design-review
• RESTful Web Service
• http://terasolunaorg.github.io/guideline/1.0.1.RELEASE/ja/ArchitectureInDetail/REST.html#resthowtodesignassignuri
• RESTとROA
• http://blogs.ricollab.jp/webtech/wp-content/uploads/2008/02/rest_and_roa.pdf
ご静聴ありがとうございました
Recommended