読者です 読者をやめる 読者になる 読者になる

Programming log - Shindo200

イベント参加記録とプログラミング系の雑記

URI はクライアントにとって不透明であるべき?

よちよち.rb で『Web を支える技術』の読書会をしています。先日、P.63「5.6 URIの不透明性」の部分を読み合わせてのですが、ここに書いてあることがよくわかりませんでした。この章での主張を引用します。

URI の内部構造を想像して操作したり、クライアント側でURIを構築したりしてはいけません。なぜなら、サーバ側の実装でURIの構造を変更したとたんにシステムが動かなくなってしまう、いわゆる密結合状態になるからです
 このように、URIをクライアント側で組み立てたり、拡張子からリソースの内容を推測したりできないことを、「URIはクライアントにとって不透明(Opaque)である」と言います。

「クライアントにとって不透明ではない URI を使うと密結合状態になってしまうのではないか」ということが書かれていますが、本当にそんなことになるのでしょうか?

疑問点

クライアントにとって不透明ではない URI を使うと、本当に密結合状態になってしまうのか?

不透明ではない URI とは?

「不透明ではない URI」とは、拡張子からリソースの内容を推測しやすい URI 構造ということになります。書籍の例を借りると

http://example.jp/2010/05/01/press.ja
http://example.jp/2010/05/01/press.en
http://example.jp/2010/05/01/press.fr

といった URI が「不透明ではない URI」になりますね。この構造はP.61 「言語を指定する拡張子」の部分で URI 設計のテクニックとして紹介されていますし、良い構造だと思うのですが、「URI は不透明であるべき」という思想から考えると、拡張子からリソース内容を推測しやすいから、あまり良くはない構造ということになってしまいます。

本当に密結合状態になるのか?

今までは上記の例のように末尾の言語コードを付ける構造にしていたとします。その後、構造を次のように変更したとします。

http://example.jp/ja/2010/05/01/press
http://example.jp/en/2010/05/01/press
http://example.jp/fr/2010/05/01/press

このような構造をしたサイトはたまに見かけますね。(例えば、『nginx news』とか。)このような構造に変更したとしても、変更後の構造を見れば「今度は "/ja/" の部分を変更すればいいのか」とすぐに気付くと思いますし、密結合状態になると主張するには弱い感じがするのですが、どうなのでしょうか。

もしかして、例がよくなかったのかも?

言語コードを付ける構造を例にしたので、密結合状態になると主張するには弱い感じになってしまったのかもしれません。でも、どういう例にしたら良いのかわかりません。困りました。

そもそも「クールな URI は変わらない」という考えがあったような

「クールな URI は変わらない」という考えがあるのに、URI が変わることを想定した思想があるのは少し不思議に感じました。

W3C の文書を見てみたけど

URI の不透明性について説明されているというW3Cの文書『Architecture of the World Wide Web. Volume One』の2.5節を見てみましょう。

私には難しい文章なのですが、翻訳してみました。(間違っていたらごめんなさい!)

In general, one cannot determine the type of a resource representation by inspecting a URI for that resource. For example, the ".html" at the end of "http://example.com/page.html" provides no guarantee that representations of the identified resource will be served with the Internet media type "text/html". The publisher is free to allocate identifiers and define how they are served. The HTTP protocol does not constrain the Internet media type based on the path component of the URI; the URI owner is free to configure the server to return a representation using PNG or any other data format.

Resource state may evolve over time. Requiring a URI owner to publish a new URI for each change in resource state would lead to a significant number of broken references. For robustness, Web architecture promotes independence between an identifier and the state of the identified resource.

(意訳)

一概には、リソースのURIを調べることで、リソース表現の種類を決定することはできません。例えば、"http://example.com/page.html" の終わりの ".html" が、MIME タイプ "text/html" で提供されるという保証にはなりません。(".html"などの)識別子をどのように提供するかは、発行者が自由に決められます。HTTP プロトコルでは URI の構成に基づいた MIME タイプを制約していません。PNG や他のデータフォーマットを使った表現を返すように設定しても構いません。

リソースの状態は時間をかけて変更していっても良いです。リソースの状態を変更するごとに、新しい URI を発行することを必要とします。(#TODO: 「in resource state would lead to a significant number of broken references.」の訳が足りない)堅牢にするために、Webアーキテクチャは識別子と識別したリソースの状態の独立性を促進します。

HTTP プロトコルでは、拡張子「html」を使っているファイルは必ずMIMEタイプを「text/html」にしないといけないとは定義されていないから、URI でリソースを判断するような作りにしてはいけないということなのでしょうか?

結論は何なのでしょうか?

結局わからずじまいです。どこかのコミュニティに疑問を持っていって、聞いてみた方が良さそう。

疑問が解決しました(2014年6月2日 追記)

@willnetさん@tkawaさんにコメント欄で教えていただき、疑問が解決しました。(詳しくはコメント欄で。)さらに、著者の山本陽平さんからもTwitterでコメントをいただきました。


ありがとうございます!