この記事はWIPです
Ruby on Rails というフレームワークはRESTというソフトウェアのアーキテクチャスタイルにとても影響を受けたWebアプリケーションフレームワークです。RailsがRESTfulに作られているお陰で僕らはRailsエンジニアは普段RESTを大きく意識することなく、(ある程度)RESTfulなWebアプリケーションやWebAPIを作れていると思います。
RESTって何という方はこちら
簡素に書くと、Webアプリケーションの構造論の一つで、Webが大成した理由の一つ。ロイ・フィールディングって天才が考えて2000年に論文として発表しました。
日本だと山本陽平さん、@tkawaさんとかがREST界隈で有名だと思います。
ROA(リソース指向アーキテクチャ)
RESTには4つの原則があって、この原則を守るアーキテクチャをROA(リソース指向アーキテクチャ)という。
- アドレス可能性(Addressability)
- サーバーが提供できる情報がすべてリソースとして公開され、一意のURIが割り当てられていること
- URIは構造的であり、予測可能であることが望ましい
- ステートレス性(Stateless)
- クライアントはリクエストごとに必要な情報をすべて送信する
- サーバーはクライアントのタイムアウト状態に配慮しない
- アプリケーションサーバーが複数ある場合は、ステートレス性によってクライアントからのリクエストを受け取りアプリケーションサーバーがリクエストごとに異なっても問題なくなる
- サーバーにはクライアントの状態(state)を保存しない設計
- ログイン機能等のために一部をstatefulにしている
- 接続性(Connectability)
- 情報の内部に、別の情報や(その情報の別の)状態へのリンクを含めることができること。
- 統一インターフェース(Uniform Interface)
- リソースに対する操作(HTTPメソッド)を統一すること
- すべてのWebが操作を抽象化することで、互換性を保つことができる(という思想だった。)
- リソースに対する操作(HTTPメソッド)を統一すること
ROAに則ることでRESTfulなWebアプリケーション, APIが作ることが可能になる。
RailsとREST
RailsアプリケーションにおいてRESTは、構成するコンポーネント (弊社でいうOfficeやUserなど) を「リソース」としてモデル化し、これらをCRUDやHTTPメソッドで操作可能にすることに利用されています。(Railsガイドから抜粋)
RailsがRESTfulなフレームワークとして成り立っているお陰で僕らはルーティングどうしようかなと悩まずに名前空間だけを決めることで最適なルーティングを即座に作ることができています( resources :books
みたいな記述でCRUD操作ができるルーティングが一瞬でできますよね?)。これはRailsのCoCという考え方によるものだと思っていて、本当に最高だと思う
ちなみにRailsはメジャーバージョンが2になったころにRESTfulルーティングを取り入れたよう。そして今も現役でRESTfulなフレームワークです 参考
Railsアプリケーション/API == RESTfulなのか?
Railsのルーティングは前述の通り本当にすごくて、開発者が意識することなくRESTfulなルーティングを作ることを可能としてくれます。しかし僕らが開発するRails wayに則ったRailsアプリケーション/APIは、Railsが提供してくれたルーティングどおりRESTfulなものでしょうか。
答えはYESでもあり、NOでもある思います。
Rails wayに則って開発しているのになぜNOと思うことがあるのかというと、例えば ......
書くの飽きた( ˘ω˘ )
悩みどころ
ムズカシイなと思うところは /books/1
というパスに対するリクエストでbook_idが1番のリソースを削除したかった時に、このアプリケーションではbookリソースの削除を論理削除で実現していた時に、HTTPメソッドを DELETE
とするか PATCH
とするかです。内部処理的には論理削除フラグを立てるためにUPDATEのSQL文が実行されているので PATCH
と思うのですが、このリクエストでは利用者は book_id1番を削除するという意思を持ってリクエストを送ってくるので DELETE
を使うべきなのかなといつも悩みます。
いろんな人に質問してみて一番しっくり来たのは、そのリソースと/books/1のURIとのマッピングがなくなるのであれば、それはDELETE。その論理削除した後も/books/1が見れるのであれば、それはPATCHを使うべきという話でした。