#はじめに
この記事を拝見して、自身でも簡単なAPIを作ってみました。
その結果、RESTやROAなどの知識が深まったので、それを共有したいと思います。
#RESTとは
分散型システムにおける、複数のソフトウェアを連携させるのに適した
設計原則の集合、考え方のこと。
その一つとして、代表的なものにROA(リソース指向アーキテクチャ)があげられる。
#ROAとは
Web上に存在する情報やデータのことをリソースとし、そのリソースを中心に考える
アーキテクチャのこと。
また、リソースがリソースであるための条件として、リソースは少なくとも一つのURIを持っている。
#ROAの特性
- アドレス可能性(Addressability)
- ステートレス性(Stateless)
- 接続性(Connectability)
- 統一インターフェース(Uniform Interface)
一つずつ見ていきましょう
##アドレス可能性(Addressability)
提供する情報がURIを通して表現できること。
全ての情報はURIで表現される一意なアドレスを持っていること。
例えば、基本のURIが下記のものだとすると
http://example.com
特定のユーザーの情報が知りたければ
http://example.com/users/1
猫の情報が知りたいなら
http://example.com/cat
ネズミの情報が知りたいなら
http://example.com/mouse
といった感じで、提供する情報がURIを見ただけで理解することが出来る。
##ステートレス性(Stateless)
HTTPをベースにしたステートレスなクライアント/サーバプロトコルであること。
セッション等の状態管理はせず、やり取りされる情報はそれ自体で完結して解釈できること。
これは下記の例えがわかりやすい
(ステートフルの例):
客: こんにちは
店員: いらっしゃいませ。○○バーガーへようこそ
客: ハンバーガーセットをお願いします
店員: サイドメニューは何になさいますか?
客: ポテトで
店員: ドリンクは何になさいますか?
客: ジンジャーエールで
店員: +50円でドリンクをLサイズにできますがいかがですか?
客: Mでいいです
店員: 以上でよろしいですか?
客: はい
店員: かしこまりました
(ステートレスの例):
客: こんにちは
店員: いらっしゃいませ。○○バーガーへようこそ
客: ハンバーガーセットをお願いします
店員: サイドメニューは何になさいますか?
客: ハンバーガーセットをポテトでお願いします
店員: ドリンクは何になさいますか?
客: ハンバーガーセットをポテトとジンジャーエールでお願いします
店員: +50円でドリンクをLサイズにできますがいかがですか?
客: ハンバーガーセットをポテトとジンジャーエール(M)でお願いします
店員: 以上でよろしいですか?
客: ハンバーガーセットをポテトとジンジャーエール(M)でお願いします。以上
店員: かしこまりました
店員をサーバーととらえて考えると、店員が一人の客にずっと対応していると、
その間は他の客に対応することができない。店が混んできたら(アクセスが増加したら)
店員を増員して(WEBサーバを増設して)対応する。
普通の店舗では一つのレジで一人の店員がずっと同じ客を受け付けるのだが、
WEBの場合は複数のWEBサーバで複数のクライアントを同時にうけつけるため、
ステートレスサーバであれば、上記の様に各インタラクションで別々の店員が
客の注文をに応答することが可能になる。
出典 ステートレスとは
##接続性(Connectability)
情報の内部に別の情報やその情報へのリンクを含めることができること。
##統一インターフェース(Uniform Interface)
情報の操作(取得、作成、更新、削除)は、全てHTTPメソッド(GET、POST、PUT、DELETE)
を利用すること。
###GET
指定したURIの情報を取得するメソッド。
Webページ、画像、映像、フィードの取得などがこれに当たる。
###POST
POSTには以下の3つの役割がある。
####1. 親リソースに対して子リソースの作成
例えば、このようなブログのリソース(親)があるとする。
http://example.com/myblog
そうしたら、個々のブログエントリ(子リソース)を、
http://example.com/myblog/entries/1
として提供することができる。
####2. リソースへのデータの追加
既存のリソースにデータを追加する。先ほどとの違いは、リソースに親子関係があるかどうか。
http://example.com/myblog
####3. オーバーロードPOST
他のメソッドでは対応できない処理の実行を行う。
ただ、この使い方はROAにおける統一インターフェースから外れるため、極力使わない方がいい。
PUT
PUTには2つの使い方がある。
- 新規リソースの作成
- 既存リソースの更新
これだけ見ると、POSTと役割が似ているように思えるかもしれない。
親リソースに対して子リソースの作成 = 新規リソースの作成
リソースへのデータの追加 = 既存リソースの更新
実際、明確な正解はないらしい。ただ、設計上の指針として以下の指針が存在する。
これには正解は存在しませんが、設計上の指針として次の事実があります。POSTでリソースを作成する場合、クライアントはリソースのURIを指定できません。URIの決定権はサーバ側にあります。逆にPUTでリソースを作成する場合、リソースのURIはクライアントが決定します。 (中略) 一般的に、クライアントがリソースのURIを決定できるということは、クライアントを作るプログラマがサーバの内部実装(URIにどの文字を許すのか、長さの制限はどれくらいかなど)を熟知していなければなりません。 そのため、PUTのほうがどうしてもサーバとの結合が密になります。特別な理由がない限りは、リソースの作成はPOSTで行いURIもサーバ側で決定する、という設計が望ましいでしょう。
[出典 Webを支える技術 ── HTTP,URI,HTML,そしてREST]
また、このPOSTとPUTの違いについて調べた時に、このような質問を見つけた。
REST APIにおいて更新のみを行うPUT処理は適切か
これらの内容を加味すると、リソースの新規作成はPOST、更新を行う場合であればPUT。
DELETE
クライアントは不要なリソースを削除する場合に、そのURIにDELETEリクエストを
送信してリソースを削除する。
以上が統一インターフェイスについてです。
#おまけ CRUDとは
クラッド (CRUD)とは、システムに必要な4つの主要機能である
「Create(生成)」「Read(読み取り)」「Update(更新)」「Delete(削除)」の並べた用語
HTTPメソッドのうちGET、POST、PUT、DELETEは「CRUD」を満たす
CURD名 | 意味 | メソッド |
---|---|---|
Create | 作成 | POST/PUT |
Read | 読み込み | GET |
Update | 更新 | PUT |
Delete | 削除 | DELETE |
#おまけのおまけ Railsのresourcesについて
Railsでは、以下のような記述をすることが出来る。
Sampleapp::Application.routes.draw do
resources :users
end
そしてこのコードは、以下のようなルーティングを定義してくれる
URL | アクション | HTTPメソッド | 動作 |
---|---|---|---|
/users | index | GET | ユーザ一覧画面を表示 |
/users | create | POST | ユーザの登録処理 |
/users/new | new | GET | ユーザの登録画面を表示 |
/users/1/edit | edit | GET | ユーザの編集画面を表示 |
/users/1 | show | GET | ユーザの詳細画面を表示 |
/users/1 | update | PATCH | ユーザの更新処理 |
/users/1 | update | PUT | ユーザの更新処理 |
/users/1 | destroy | DELETE | ユーザの削除処理 |
これだけのコードで、RESTfulに対応できるのは便利ですね。