現在、一般的になりつつある REST (REpresentational State Transfer) ですが、いざ実践しようとするためには、正しい理解と実装指針が必要です。前編となる本記事では、REST の概念をご紹介し、後編となる次記事では、一般的に言われている勘所と、私が実プロジェクトで実践した勘所についてご紹介します。

1. SaaS/PaaSとREST

SaaS(Software as a Service)やPaaS(Platform as a Service)、クラウドといった言葉をよく耳にします。
Web上に公開されているサービスを、あたかもクライアントPCにインストールされているソフトウェア(アプリケーション)のように扱えるSaaS。Webの向こう側に存在するインフラ基盤を、あたかも自身で用意したプラットフォーム(実行基盤)のように扱えるPaaS。有名どころでは、Google Docs & SpreadsheetsやAmazon Simple Storage Service(S3), Amazon Elastic Compute Cloud(EC2)などがあり、また、MicrosoftもAzure Services Platformと呼ばれるクラウド向けプラットフォームを発表しています。

SaaSやPaaSがどのようなもので、今後どのように発展するかという点については、本記事の範疇外なので省略させて頂くとして、これらのサービスを見てみると『REST』というキーワードを目にすることがあります。

Amazon S3(※1) サービスのサイトには、『REST API』というリンクがあります。Amazon Web Service(AWS)でも同様にREST APIが提供されています。Windows Azure Storage サービスのサイトを見てみても、同じようにREST APIが用意されていることが分かります。

RESTとは一体何でしょう?SOAPと同列に扱われていますので、プロトコルのようにも見えますし、APIを見てみると何やらURLパラメータがいくつも定義されています。勘の良い方、もしくは既にご存知の方は、「あるURLにリクエストを送信し結果を得るもの」ということがご理解頂けるでしょう。
ここではストレージサービスを例に挙げましたが、RESTは新しい潮流の中に組み込まれており、無視出来ないものとなっています。RESTはSOAPのようなプロトコルではありませんし、オブジェクト指向のように難しいものでもありません。『ほんの少し』HTTPの考え方を整理したものなのです。

RESTはコンシューマに対してサービスを公開するインタフェースとしての役割だけでなく、分散型システムの連携手法として採用することも出来ます。
本記事ではRESTのコンセプトや特徴、誤解、また導入する際の勘どころについてお話していきます。
もし皆さんがサービス(インタフェース)を提供する側になった場合、またはそうでなくても分散型システム連携の設計者となった場合に、本記事が設計時の手助けとなれば幸いです。

※1:
Amazon S3はその名の通り、ストレージ(ハードディスクなどのような記憶域)をコンシューマに提供するサービスです。

2. 過去の分散型システム連携というと...

これまで、分散型システムにおける通信手段を設計・実装するための『数多くの』議論がなされてきました。過去のもので言うとCORBAやDCOMなどが一般的ですが、当時、一世を風靡したその仕様群も、策定されては衰退、策定されては衰退を繰り返し、開発者は新しい技術が出てくる度にそれらを学習、導入して来ました。しかしサポート切れなどにより、数年後には大々的なリプレースを余儀なくされ、その都度新しい技術を学習し直さなければならないといったスパイラルに苛まれてきました。

また、プロジェクトが変わればそこでまた新しい技術を学ぶといった、ある意味その場をやり過ごすためだけの学習をしなければならなかったのが実情です(※2)。

新しい技術が出てくる度に学習するのは大変・・・

※2:
それが好きな技術者もたくさんいますし否定はしません。あくまで、「そういう場面が多い」というだけのお話です。

3. 最近ではSOAPによる連携が主流だが...

現在ではSOAP, WS-*を用いたWebサービス連携がメインストリームとなり、学習しなければならない周辺仕様は依然多いものの、方向性はほぼ一本化されてきました。しかし、SOAPは技術的に明るくない人々にとっては敷居が高いので、少数派の技術者は『より良い手法』を模索してきました。
ここで注目されているのがREST(REpresentational State Transfer)です。RESTは特定の技術やプロトコルではなくスタイル、言い換えると『考え方』を指していますので、技術に明るくない人々にとっても分かり易く、また開発者にとっても技術に振り回されることのない普遍的なものと言えます。

『考え方』は長い期間いろいろなプロジェクトで使える

REST自体は2002年頃から注目され始めていたのですが、「HTTPとXMLを使ったSOAPより軽いWebサービス」だとか、「SOAPのようなover HTTPなテクノロジ」といった誤解された解釈で一般的に流通しているのが実情です。しかし、RESTには原理原則があり、単なる「HTTPとXMLを使ったWebサービス」ではRESTとは言えません。RESTという仮面をかぶったRPC(Remote Procedure Call)でしかありません。

RESTは単なるHTTP+XMLではない / RESTはHTTPの原理原則上に成り立っている

以降、RESTの原理原則や特徴などを紹介していきたいと思います。

4. RESTはHTTP仕様に準拠したWebサービス

RESTは、Roy Fieldingという方が、2000年に発表した博士論文で提唱されたアーキテクチャスタイルです。Roy FieldingさんはHTTP仕様の策定者の一人であったことから、HTTPはRESTの基準をよく満たしています。
一般的にWebサービスと言うと、SOAPを思い浮かべる方が多いでしょう。しかし、SOAPはHTTPやFTP, SMTPなどの特定の下位プロトコルに依存しませんし、WS-AddressingやWS-Securityといった多くの周辺仕様(WS-*で表現されるもの)があり、その全容を理解するのはなかなか難しいです。
また、SOAPによるWebサービスでは、技術的にも容易に接続することが出来ません。

SOAPは下位プロトコルから独立している / SOAPは多くの周辺技術で成り立っている

一方RESTは、World Wide Webにも適用されているHTTP仕様の上でのみ成立します。既に普及しているHTTPをベースとしていますので、容易に接続することも出来ますし、みなさんは既に多くのことを知っています。そう。ブラウザにURLを入力するとページや画像が表示されますね。アメブロやmixiに日記を書いた後、[送信]ボタンを押してサーバーにアップ(送信)しますね。RESTはこういった操作(サービス)をHTTPという軽量なプロトコル上に載せた、いわばWebという既存のインフラをフル活用した古典的なWebサービスであると言えるのです。

RESTはHTTPというプロトコルと仕様上にのみ成り立っている

なお、SOAPによるWebサービスではメッセージ形式はXMLと規定されていますが、RESTによるWebサービスではメッセージ形式は規定されていません。ほとんどの場合はXMLを使用しますが、HTMLやJSON、プレーンテキストでもバイナリデータでも構いません。HTTP仕様ではメッセージ形式を規定していないので、RESTも同様にメッセージ形式を規定していません。

5. RESTのコンセプトと特徴

ここからはRESTのコンセプトとその特徴についてお話していきます。
RESTは、おおよそ以下のコンセプトの上に成り立っています。

リソース指向

それ自体を参照するに値するもの全てをリソースとして扱います。リソースは状態を持つことも出来ます。

例えば、以下のものはリソースとして考えられます。

  • 任天堂Wiiのスペック情報
  • 株式会社 豆蔵の事業概要
  • trac(バグトラッキングシステム)のチケット
  • 株式会社 豆蔵のコーポレートロゴ
  • 10番目の素数
  • Aさんの2008年11月10日のブログ

URIによる名前付け

全てのリソースはURIを識別子として持ちます。URIとリソースは1対1に対応付けられ、直感的かつ構造的に割り当てます。それは丁度ディレクトリ構造に類似します。

例えば、以下のようなURIが考えられます。

http://somewhere.com/blog/2007/1/20
http://somewhere.com/blog/2008/11/10
http://somewhere.com/blog/2008/11/11

表現の提供

リソースは表現を持ちます。表現とはリソースの見え方です。例えば、「2009年上半期の営業実績」というリソースがあった時、テキストとして表現することも出来るし、棒グラフや折れ線グラフ、XMLドキュメントとしても表現することが出来ます。

コンポーネント指向

リソース操作を実現するコンポーネント群が、スケーラブルに簡単な方法で連携出来ます。

あるサービスを公開する際、それがRESTと言えるものなのかどうか、またはRESTなWebサービスを実装したいのだけれど、どういう指針に基づけば良いのかという壁にぶつかります。
おおまかに纏めると、おおよそ以下の特徴を満たしているかどうかで判断出来ます。

統一インタフェース

  • 【使用しているHTTPメソッドが操作を適切に表しているかどうか。】
    • GET : リソースの取得用として使用しているか
      • 安全性(※3)を満たしているか
    • POST : リソースの新規作成用として使用しているか
      • 新たに割り当てられるURIはサーバーによって決定されるのか
    • 新しいURIへのPUT : リソースの新規作成用として使用しているか
      • べき等性(※4)を満たしているか
      • 新たに割り当てられるURIはクライアントによって決定されるのか
    • 既存URIへのPUT : リソースの更新用として使用しているか
      • べき等性を満たしているか
    • DELETE : リソースの削除用として使用しているか
      • べき等性を満たしているか
    • HEAD : メタリソースの取得用として使用しているか
      • 安全性を満たしているか
    • URIがリソースそのものを指しているか。
      • 商品情報の取得なら~/product/12-345や~/product?productID=12-345のようになっているか。~/getProduct/や~/product/get, ~/product?method=getといったように操作の一部を表していないか

※3:
安全性とは、数字に1を掛けることと同等である。10*1も10*1*1*1も同じ10であること。つまり、同じ操作を何回行っても元々の情報は変わらないということ。

※4:
べき等性とは、数字に0を掛けることと同等である。10*0も10*0*0*0も0であること。つまり、一度操作を行えば、以降は何回行っても変わらないということ。

アドレス可能性

  • リソース毎にURIが割り当てられており、いつでもどこでも、同じURIを指定したら再接続可能であるか。
    • メールに添付されたリンクをクリックしたら、いつでもどこでも同じリソースを見られるかなど

ステートレス性

  • 全てのリクエストは自己完結型となっているか。HTTPセッションなどメモリ上に情報を保持して、スティッキーセッションやレプリケーションなどを行いリクエスト間で状態を共有していないか。

その他

  • HTTPレスポンスコードを正しく使用しているか。
    • リクエストが成功したら200(OK)を返す、不正なリクエストだったら400(Bad Request)を返す、サーバーエラーが発生したら500(Internal Server Error)を返すといったように。

次回は、一般的に言われている勘所と、私が実プロジェクトで実践した勘所についてご紹介します。