はじめに
普段特に意識せず使っているRESTについてざっくりGETとかPOSTできるんだなぁくらいの理解で抽象度高すぎたので、そもそもRESTってどんなものでどんな設計になっているかまとめました。
参考情報
Webを支える技術 -HTTP、URI、HTML、そしてREST
Webの歴史
RESTに入る前の背景として、RESTとズブズブの関係であるWebの生い立ちから見ていきます。
Webの誕生と普及
まずWeb以前のインターネットでは、やりとりされる情報として学術論文がメインでハイパーテキストという文字情報を相互にリンクさせた概念で動いていました。しばらくはそれで困ってなかったのですがもっとグラフィカルな情報が見たいニーズが増えてきて、ハイパーメディアという文書以外にも画像や動画などをコンテンツにリンクさせる概念が生まれました。それが今日のWebの源流となっています。(ちなみにWeb以前にもハイパーメディアという考え方はあったものの、仕組みとしてコンテンツを双方向でリンクしてリンク切れを起こさないようにするといった仕組みも含まれていて結構複雑な作りになっていたみたいです。) -(a)
また、前述のハイパーメディアの概念が生まれるのと同時期に、分散システムといった単体の端末で全ての処理を担うのではなく複数のコンピュータを組み合わせて処理を分散させ、全体としての性能を向上させる手法が生まれました。(背景として1970年台移行コンピュータのダウンサイジングが進んで1つ1つのコンピュータが小型化し正常が向上した背景があります。) - (b)
前述の(a),(b)の背景の中でWebは生まれました。
Webはハイパーメディアの一つとして設計されており、Web以前の今までのハイパーメディアとの大きな違いとしてはそのシンプルさが挙げられます。以前のハイパーメディアでは前述のように双方向リンクなどシステムが複雑化していたのですが、Webでは単方向リンクを採用したことにより実装がシンプルかつ容易になったことでWebの普及が進みました。
また、Webはオープンな環境で不特定多数のユーザを相手にするシステムとして設計されています。
これを実現するために、Webはクライアントからサーバに対してHTTPというシンプルなプロトコルでアクセスすることを課したことにより、アクセス元となる端末のOSやハードウェアは統一されていなくとも、HTTPに乗っ取りさえすれば利用できるといった環境を作り上げました。そんな作りも相まってWebは受け入れられモリモリ普及していきます。
(Webの普及が早く進んでしまったがために、webの仕様策定が追いつかずブラウザごとで相互運用性に書ける状態が発生したらしいです。同じコンテンツでも表示するブラウザによって表示内容が変わっちゃうとか。現在でも悩まされているブラウザ対応はこの時代からあったみたいですね。)
Webの普及に伴うメディアフォーマット JSON の誕生
(ちょっと脱線します。)
初期のWebはHTMLが唯一のハイパーメディアフォーマットであったものの、Webの普及に伴ってHTMLでは対応できない、もしくはHTMLだと冗長すぎる(情報が多すぎる)コンテンツをやり取りしたいといった状況が発生します。これに対応するために生まれたフォーマットがJSONになります、
上記のHTMLでは対応できない利用用途としてWebAPIが挙げられます。初期のWebは学術論文の交換に利用される用途が主でしたが、Webの用途が多様化するに従ってプログラムから自動処理を行いたいという要求が出始めました。これによりWebAPIで利用するフォーマットとしてJSONが利用されるようになります。
REST の誕生
上記で挙げたようなフォーマットなどWebの仕様策定が定まっていない情勢の中で、RESTが誕生しました。
REST(Representational State Transfer)とは未だガチャガチャしてるWeb界隈において、一連の様式やお作法をアーキテクチャスタイルとしてまとめたものになります。
メモ
(HTTP は Hyper TextをTransferするプロトコルであったのに対して、RESTではテキスト以外のResourceのStateをTranferする考え方でこんな名前になってます。)
(RESTのライバルとして当時SOAPが流行っていたが、Web2.0の流れの中で「アプリケーションを実現するためにいろいろなWebAPIが提供する情報を組み合わせる(マッシュアップする)」考え方が主流となりRESTが受け入れられました。)
アーキテクチャスタイルとしてのREST
前述のRESTは、数あるアーキテクチャスタイルの中でもネットワークシステムに関するアーキテクチャスタイルとなっています。
Webがそもそもクライアント/サーバ形式のアーキテクチャスタイルですが、RESTはそれにさらに制約を加えたアーキテクチャスタイルになります。
RESTはWeb全体のアーキテクチャスタイルでもあり個別のWebサービスやAPIのアーキテクチャスタイルでもあります。そのため、サービスやAPIを作る際はRESTの約束を守らないと統一されたアーキテクチャスタイルを守ることができなくなります。
アーキテクチャスタイルのRESTを見ていく前に、重要な概念として「リソース」について示します。
- リソースとはWeb上の情報である
- 世界中の無数のリソースはそれぞれURIで一意の名前を持つ
- URLを用いることで、プログラムはリソースが表現する情報にアクセスできる
ざっくりWeb上で提供されている、情報を返却してくれるURIのこと。
RESTのアーキテクチャスタイルについて
前述のようにRESTはクライアント/サーバ形式をもとにしたアーキテクチャスタイルです。
クライアント/サーバ形式
クライアント/サーバの利点として、全ての処理を単一の端末上で処理するのではなく、クライアントとサーバに分離して処理を行うことができる点が挙げられます。これによりクライアントをPCや携帯端末といったマルチプラットフォームにすることができます。
さらに、ユーザインタフェースはクライアントが担当するため、サーバはデータストレージとしての機能に集中することができます。
ここまでがRESTのベースとなるクライアント/サーバの考え方となります。これにさらに概念を追加していくことでRESTが構成されます。
ステートレスサーバ
前述のクライアント/サーバにステートレスサーバの概念を追加します。ステートレスとはクライアントのアプリケーション状態をサーバ側で管理しないことを意味します。
この利点としてサーバ側が処理を簡略化することができます。(クライアントの処理に答えたらすぐにリソースを解放することができる)
現実にはCookieセッションを使ったステートフルな実装は多くありますが、実はRESTと概念とは離れています。ステートレスであることの利点を捨てている点は理解して使う必要があります。
キャッシュ
ここまでのアーキテクチャスタイルにキャッシュを追加します。
キャッシュはリソースの鮮度に基づいて一度取得したリソースを使い回す仕組みになります。これによってクライアントとサーバ間の通信を減らすことでより効率的に処理を進めることができます。デメリットとしては古いキャッシュを利用することによる情報の信頼性が下がることが挙げられます。
統一インタフェース
次に統一インタフェースをアーキテクチャスタイルに追加します。統一インタフェースとは、URIで指し示したリソースに対する操作を統一した限定的なインタフェースで行うことを指します。(GET/POST...とかのこと)
これにより、全体のアーキテクチャがシンプルになりクライアントとサーバの実装の独立性が向上します。
この統一インタフェースはRESTを最も特徴付けるアーキテクチャスタイルといえます。
階層化システム
前述の統一インタフェースの更なる利点の一つに、システム全体を階層化しやすくなることが挙げられます。
インタフェースが統一化されていることによって、クライアントはどのサーバに対しても同じインタフェースでアクセスすることができます。ひいてはクライアントは接続先がプロキシであっても特に意識する必要なく同じインタフェースでアクセスすることができます。
そのためクライアントとサーバの間にロードバランサといったプロキシを挟むような階層構造のシステムを構築しやすくなることも利点として挙げられます。
コードオンデマンド
最後に、ここまでのアーキテクチャスタイルにコードオンデマンドを追加します。
コードオンデマンドとはサーバから提供されたプログラムコードをクライアント上で実行することを指します。これにより、クライアントが用意してい機能だけではなくサーバ側から提供した機能を追加することができます。
欠点としてネットワーク通信におけるプロトコルの可視性が低下することが挙げられます。HTTPというプロトコルに則って通信をしている間はその通信の意味は明白であるものの、コードオンデマンドでクライアント上で実施される処理については可視性が低下する(クライアントで何してるかわからない)問題があります。
まとめ
ここまでのアーキテクチャスタイルを組み合わせた複合アーキテクチャスタイルのことを REST と名付けられています。
-
クライアント/サーバ:ユーザインタフェースと処理を分離する
-
ステートレスサーバ:サーバ側でアプリケーション状態を持たない
-
キャッシュ:クライアントとサーバの通信回数を減らす
-
統一インタフェース:インタフェースを固定する
-
階層化システム:システムを階層に分離する
-
コードオンデマンド:クライアントでプログラムを実行する
実現したいものとして、そもそもサーバが必要なくPeer同士で通信が必要であるといった要件がある場合は、無理にRESTを採用せずP2Pを利用するなど要件に合わせて利用・設計が必要になります。
普段使ってるGET,POSTは統一インタフェースによる産物で、そのおかげで処理がある程度制限されて実装としてはシンプルになってる(統一インタフェースが用意するAPIの設計にも関わってきてる)みたいですね。