狠狠撸

狠狠撸Share a Scribd company logo
RESTful API設計入門
2015/1/30
自己紹介
Speaker : {
name : 薬師寺 信勝
company : 株式会社モンスター?ラボ ,
department : 音楽事業部 ,
}
目次
? REFTfulとは
? 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/identi?er/collection以上深くすべきでない
? URLは浅く保ち複雑さはクリエリパラメータに
URL(例)
? メンバーリスト
? /members
? メンバーID1234
? /members/1234
? グループ
? /groups
? /groups/1234
? /getGroup -> 動詞は使わない
バージョン
? APIのバージョンをURLに付与する
? /v1/members
? URLに付与するとブラウザ等で呼び出しやすい
? 機能変更による振る舞いの変化に対応しやすい
? 市場に出ている古いバージョンのクライアント
に対応できる
Partial response
? 利用者が指定したデータだけ返す。
? ?eldsパラメータにカンマ区切りで指定
? /members/1234??elds=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と同じ処理を行いヘッダ情報の
み取得。
OPTIONS
URIで指定されたリソースでサポートされている
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 Created
POSTメソッドを使用して、新しいリソースを作成し
た際に使用する。レスポンスのLocationヘッダに、
作成したリソースのURIを設定する。
204 No Content.
リクエストが成功した結果として、レスポンスのエ
ンティティボディに、リクエストに対応するリソー
スの情報を出力しない時に応答する。
300系
ステータスコー
ド
説明
301
Moved Permanently
恒久的移動
303
See Other
リクエストに対するレスポンスは異なるURIの下で発見でき、そのリソー
スをGETメソッドを使って検索することが望ましい。
304
Not Modi?ed
変更なし。リクエストされたリソースが指定された日付以降に更新されていない。クライアントが条
件付きGETリクエストを実行し、アクセスは許可されたが、ドキュメントが更新されていない場合に
は、サーバはこのステータス?コードでレスポンスを行なうべきである。
400/500系
ステータ
スコード
説明 適用条件
400 Bad Request
エンティティボディに指定されたJSONやXMLの形式不備を検出した場
合や、JSONやXML又はリクエストパラメータに指定された入力値の不
備を検出した場合に応答する。
401 Unauthorized 認証が必要なURLに対して認証していない場合。
404 Not Found
指定されたURIに対応するリソースがシステム内に存在しない場合に応
答する
409 Con?ict
排他エラーが発生した場合や業務エラーを検知した場合に応答する。
エンティティボディには矛盾の内容や矛盾を解決するために必要なエラ
ー内容を出力する必要がある。
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
ご静聴ありがとうございました

More Related Content

Rest ful api設計入門