概要
本記事はRoy T. Fielding氏によるRESTについての論文Architectural Styles and the Design of Network-based Software Architecturesの6.2章を翻訳したものである。
また本記事の大半はDeepL、Google翻訳を用いて翻訳を行っているため、誤訳等がありましたらご指摘ください。
6.2 URIに適用されるREST
URI(Uniform Resource Identifiers)は、Webアーキテクチャの最も単純な要素であり、最も重要な要素です。 URIは、WWWアドレス、ユニバーサルドキュメント識別子、ユニバーサルリソース識別子1、そして最後にURI(Uniform Resource Locator)2と名前(URN)3の組み合わせなど多くの名前で知られています。 その名前は別として、URI構文は1992年以来比較的変更されていません。しかし、Webアドレスの仕様は、リソースを意味するものの範囲とセマンティクスも定義しており、これは初期のウェブアーキテクチャの頃から変化しています。 RESTは、URI標準4のためのリソースという用語を定義するために使われただけでなく、その表現を介してリソースを操作するための一般的なインタフェースの全体的な意味論も定義しています。
6.2.1 リソースの再定義
初期のWebアーキテクチャでは、URIをドキュメントの識別子として定義していました。作成者は、ネットワーク上のドキュメントの場所に関して識別子を定義するように指示されていました。そうすれば、そのドキュメントを取得するためにWebプロトコルが使用されます。ただし、この定義は、いくつかの理由で不十分であることが判明しました。まず、作成者が転送されたコンテンツを識別していることを示唆していおり、コンテンツが変更されるたびに識別子が変更される必要があることを意味します。第二に、ドキュメントではなくサービスに対応する多くのアドレスが存在します。作成者は、読者をそのサービスに誘導することを意図しているのであって、そのサービスの事前のアクセスから得られる特定の結果に誘導することを意図しているのではないかもしれません。最後に、ドキュメントがまだ存在しない場合や、アドレスが情報を見つけるのではなく名前を付けるためだけに使用されている場合など、特定の時期にはドキュメントに対応しないアドレスも存在します。
RESTにおけるリソースの定義は、識別子は可能な限り頻繁に変更されないようにすべきであるという単純な前提に基づいています。Webはリンクサーバーではなく埋め込み型の識別子を使用するため、作成者はハイパーメディア参照によって意図するセマンティクスに厳密に一致する識別子を必要とします。これにより、参照へのアクセス結果が時間の経過とともに変化する場合でも、参照を静的に保つことができます。 RESTは、参照の作成時にそれらのセマンティクスに対応する値ではなく、作成者が識別しようとしているもののセマンティクスになるようにリソースを定義することによってこれを実現します。そして、参照のために選択された識別子が実際に意図されたセマンティクスを識別していることを確認するのは作成者に任されています。
6.2.2 影の操作
URIがドキュメントではなく概念を識別するようにリソースを定義すると、ハイパーテキストリンクが選択されたときに、ユーザーが概念にアクセス、操作、または転送して、何か役立つものを取得するにはどうすればよいかという別の疑問が残ります。RESTは、操作されるものをリソース自体ではなく、識別されたリソースの表現であると定義することによって、この疑問に答えています。オリジンサーバーは、リソース識別子から各リソースに対応する表現のセットへのマッピングを保持します。したがって、リソースは、リソース識別子によって定義された汎用インターフェースを介して表現を転送することによって操作されます。
RESTのリソースの定義は、Webの中心的な要件である複数の信頼ドメイン間で相互接続されたハイパーテキストの独立したオーサリングに由来します。インターフェースの定義をインターフェースの要件に一致させると、プロトコルが曖昧に見えてしまいますが、これは、操作されるインターフェースがインターフェースのみであり、実装ではないためです。プロトコルはアプリケーションのアクションの意図を具体的に示していますが、インターフェースの背後にあるメカニズムは、その意図が表現へのリソースマッピングの基礎となる実装にどのように影響するかを決定する必要があります。
情報の隠蔽は、RESTの統一インターフェースを動機付ける重要なソフトウェア工学の原則の1つです。クライアントは、リソースの実装に直接アクセスするのではなく、表現の操作に制限されているため、実装はその表現を使用する可能性のあるクライアントに影響を与えることなく、命名権者が希望するどのような形式でも実装を構築することができます。さらに、リソースへのアクセス時にリソースの複数の表現が存在する場合、コンテンツ選択アルゴリズムを使用して、そのクライアントの機能に最適な表現を動的に選択できます。もちろん、リソースのリモートオーサリングはファイルのリモートオーサリングほど単純ではないという欠点があります。
6.2.3 リモートオーサリング
Webの統一インターフェースを介したリモートオーサリングの課題は、クライアントが取得できる表現と、その表現のコンテンツを保存、生成、または取得するためにサーバーで使用される可能性のあるメカニズムとの間に分離があることにあります。個々のサーバーは、名前空間の一部をファイルシステムにマップすることができ、それはディスクの位置にマップできるiノードに相当するものにマップされますが、これらの基本的なメカニズムは、リソース自体を識別するのではなくリソースを一連の表現に関連付ける手段を提供します。多くの異なるリソースが同じ表現にマップされることもありますが、他のリソースには表現がまったくマップされていない場合もあります。
既存のリソースを作成するためには、作成者は最初に特定のソースリソースURI(ターゲットリソースのハンドラーの基本的な表現にバインドされるURIのセット)を取得する必要があります。リソースは常に単一のファイルにマップされるわけではありませんが、静的ではないすべてのリソースは他のリソースから派生したものであり、派生ツリーを辿ることで、作成者は最終的にはリソースの表現を修正するために編集する必要のあるすべてのソースリソースを見つけることができます。これらの同じ原則は、コンテンツネゴシエーション、スクリプト、サーブレット、管理された構成、バージョン管理などからのものであるかどうかにかかわらず、あらゆる形式の派生表現に適用されます。
リソースはストレージオブジェクトではありません。リソースは、サーバーがストレージオブジェクトを処理するために使用するメカニズムではありません。リソースは概念的なマッピングです。サーバーは識別子(マッピングを識別するもの)を受け取り、それを現在のマッピング実装(通常はコレクション固有のディープツリー探索やハッシュテーブルの組み合わせ)に適用して、現在責任のあるハンドラーを見つけ、ハンドラー実装は、リクエストの内容に基づいて適切なアクションとレスポンスを選択します。これらの実装固有の問題はすべて、Webインターフェイスの背後に隠されています。それらの性質は、Webインターフェイスを介してのみアクセスできるクライアントでは想定することはできません。
例えば、あるWebサイトがユーザーベースで拡大し、XOSプラットフォームをベースにした古いBrand XサーバーをFreeBSDで動作する新しいApacheサーバーに置き換えることをにした場合に何が起こるかを考えてみましょう。ディスクストレージのハードウェアが交換されます。オペレーティングシステムが交換されます。 HTTPサーバーが置き換えられます。おそらく、すべてのコンテンツに対するレスポンスを生成する方法でさえ置き換えられます。ただし、変更する必要がないのはWebインターフェースです。正しく設計されている場合、新しいサーバーの名前空間は古いサーバーの名前空間を反映できます。つまり、リソースについてしか知らず、リソースがどのように実装されているかについては知らないクライアントの視点からは、サイトの堅牢性が向上したこと以外は何も変わりません。
6.2.4 セマンティクスのURIへのバインド
上述したように、リソースは多くの識別子を持つことができます。言い換えると、サーバーへのアクセスに使用されるときに等価なセマンティクスを持つ2つ以上の異なるURIが存在する可能性があります。また、サーバーへのアクセス時に同じメカニズムが使用される結果となる2つのURIを持つことも可能ですが、それらは同じことを意味しないため、2つの異なるリソースを識別することも可能です。
セマンティクスはリソース識別子の表現を割り当て、これらのリソースが表現に現れる行為の副産物です。サーバーまたはクライアントソフトウェアがURIの意味を認識または理解する必要は一切なく、リソースの作成者(人間の命名機関)が表現をによって識別されるセマンティクスに関連付けることができる導管として機能するだけです。言い換えれば、サーバー上にはリソースは存在しません。リソースによって定義された抽象的なインターフェース全体に回答を提供するメカニズムにすぎません。奇妙に思えるかもしれませんが、これこそがWebをこれほどまでに多くの異なる実装で動作させる本質です。
完成した製品を構成するために使用されるコンポーネントの特性の観点から物事を定義することは、すべてのエンジニアの性質です。 しかし、Webはそのようには機能しません。 Webアーキテクチャは、アプリケーションの動作中の各コンポーネントの役割に基づいて、コンポーネント間の通信モデルに対する制約で構成されています。これにより、コンポーネントがリソースの抽象化を超えて何かを想定することができず、その結果、抽象化されたインターフェースのどちら側にも実際のメカニズムが隠されてしまうのです。
6.2.5 URIにおけるRESTのミスマッチ
ほとんどの実際のシステムと同様に、展開されたWebアーキテクチャのすべてのコンポーネントが、アーキテクチャ設計に存在するすべての制約に従うわけではありません。 RESTは、アーキテクチャの改善を定義する手段と、アーキテクチャの不一致を特定する手段の両方として使用されてきました。不一致は、無知または見落としが原因で、アーキテクチャ上の制約に違反するソフトウェア実装が展開された場合に発生します。一般に不一致を回避することはできませんが、標準化される前に不一致を特定することは可能です。
URIの設計はRESTの識別子のアーキテクチャ上の概念と一致しますが、構文だけでは、命名機関がリソースモデルに従って独自のURIを定義させるには不十分です。悪用の1つの形式は、ハイパーメディア応答表現によって参照されるすべてのURI内に現在のユーザーを識別する情報を含めることです。このような埋め込まれたユーザーIDを使用して、サーバー上のセッション状態を維持したり、アクションをログに記録してユーザーの行動を追跡したり、複数のアクション(Hyper-Gのゲートウェイ5など)間でユーザー設定を伝達したりできます。ただし、RESTの制約に違反することにより、これらのシステムは共有キャッシュが効果的でなくなり、サーバーのスケーラビリティを低下させ、ユーザーがそれらの参照を他のユーザーと共有すると望ましくない影響をもたらす原因となります。
また、ソフトウェアがWebを分散ファイルシステムとして処理しようとすると、RESTのリソースインターフェイスとの別の競合が発生します。ファイルシステムは情報の実装を公開するため、負荷分散とコンテンツをユーザーの近くに再配布する手段として、その情報を複数のサイトに「ミラーリング」するツールが存在します。ただし、ファイルには簡単に複製できる固定されたセマンティクスのセット(名前付きのバイトシーケンス)があるため、そうすることしかできません。対照的に、Webサーバーのコンテンツをファイルとしてミラーリングしようとすると、リソースインターフェイスがファイルシステムのセマンティクスと常に一致するとは限らず、データとメタデータの両方が表現のセマンティクスに含まれ、それが重要であるため失敗します。Webサーバーのコンテンツはリモートサイトで複製できますが、サーバーのメカニズムと構成全体を複製するか、静的であることがわかっている表現を持つリソースのみを選択的に複製することができます(例えば、キャッシュネットワークは Web サイトと契約して、特定のリソース表現をインターネット全体の「エッジ」に複製することで、レイテンシを減らし、オリジンサーバーから負荷を分散させるようにしています)。
-
T. Berners-Lee. Universal Resource Identifiers in WWW. Internet RFC 1630, June 1994. ↩
-
T. Berners-Lee, L. Masinter, and M. McCahill. Uniform Resource Locators (URL). Internet RFC 1738, Dec. 1994. ↩
-
K. Sollins and L. Masinter. Functional requirements for Uniform Resource Names. Internet RFC 1737, Dec. 1994. ↩
-
T. Berners-Lee, R. T. Fielding, and L. Masinter. Uniform Resource Identifiers (URI): Generic syntax. Internet RFC 2396, Aug. 1998. ↩
-
H. Maurer. HyperWave: The Next-Generation Web Solution. Addison-Wesley, Harlow, England, 1996. ↩