前回は、Webの設計思想であるRESTについてまとめた。ここでは、リソースを統一的に識別するIDであるURIの仕様について説明する。
1 URIの重要性
URI(Uniform Resource Identifier)とは、統一リソース識別子と訳され、リソースを統一的に識別するIDのことである。統一的とはすべてが同じルールに従っているということで、識別子とはあるものを他のものと区別して指し示すための名前/IDのこと。URIを使うことで、Web上に存在するすべてのリソースを一意に示すことができる。
2 URIの構文
簡単なURIの例
URIの仕様はRFC3986である。例えば「http://kaihooo.com/uri-specification」を構成するパーツは、以下の通り。
- URIスキーム:http
- ホスト名 :kaihooo.com
- パス :/uri-specification
URIはURIスキーム(URI Scheme)で始まる。URIスキームは、そのURIが利用するプロトコルを示すのが一般的である。その後ろに続く部分は「://」で区切られる。次にホスト名が出現する。ホスト名はDNS(Domain Name System)で名前が解決できるドメイン名かIPアドレスで、インターネット上で必ず一意になる。最後に階層を表すパスが続く。パスはそのホストの中でリソースを一意に指し示す。
複雑なURIの例
複雑なURIの例として「http://kosuke:pass@kaihooo.com:8000/search?q=test&debug=true#n10」を見てみる。このURIは以下のように分けられる。
- URIスキーム :http
- ユーザ情報 :kosuke:pass
- ホスト名 :kaihooo.com
- ポート番号 :8000
- パス :/search
- クエリパラメータ:q=test&debug=true
- URIフラグメント :#n10
URIスキームの次にユーザ情報が入っている。ユーザ情報は、このリソースにアクセスする際に利用するユーザ名とパスワードからなる。ユーザ名とパスワードは「:」で区切る。ユーザ情報の次に区切り文字である「@」が入り、その後ろにホスト情報が続く。ホスト情報はホスト名とポート番号からなり、両者は「:」で区切られる。ポート番号は、このホストにアクセスするときのプロトコルで用いるTCPのポート番号を示す(HTTPのデフォルト値は80番)。
パスの後ろに区切り文字である「?」が付き、名前=値形式のクエリが続く。クエリが複数あるときは「&」でつなぐ。1つ以上のクエリの集合をクエリパラメータ(Query Parameter)またはクエリ文字列(Query String)と呼ぶ。クエリパラメータは、例えば検索サービスに検索キーワードを渡すときなど、クライアントから動的にURIを生成するときに利用する。
最後の「#」で始まる文字列はURIフラグメント(URI Fragment)という。URIフラグメントは、その前までの文字列で表現するURiが指し示すリソース内部の、さらに細かい部分を特定するときに利用する。
3 絶対URIと相対URI
URIのパスは、UNIXのファイルシステムと同じような階層構造を持っている。すなわち「/」をルートとして、ディレクトリ名を「/」で区切り、必要であれば最後にファイル名を接続する記法である(文書と文書をしまう場所ファイルとディレクトリ基礎知識3選参照)。
OSのファイルシステムにおける絶対パス(Absolute Path)とは、ルートから記述したパスのことである。これに対して、カレントディレクトリ(現在のディレクトリ)から記述したパスのことを相対パス(Relative Path)と呼ぶ。URIも同様に、絶対URIと相対URIがある。相対URIは、URIスキームやホスト名を省いて、パスだけで表現する。
ベースURI
ベースURI(Base URI、基底URI)とは、相対URIの起点となるURIのこと。相対URIを絶対URIに変換する(相対URIを解決する)ためには、ベースURIが必要である。
リソースのURIをベースURIとする方法
リソースのURIをベースURIにするのは直感的でわかりやすいが、ベースURiとなるリソースのURIをクライアント側で保存しておかなければならないという問題がある。
ベースURIを明示的に指定する方法
先ほどの問題を解決する方法の1つが、HTMLやXMLの中で明示的にベースURiを指定する方法である。HTMLの場合は<head>要素の中に<base>要素を入れる。XMLの場合はxml:base属性を利用すれば、どの要素でもベースURIを指定できる。
4 URIと文字
URIで使用できる文字
URI仕様では、次の文字がURIのパスに使えると定められている。
- アルファベット:A-Z a-z
- 数字 :0-9
- 記号 :-.~:@!$&'()
この文字列はASCII(American Standard Code for Information Interchange)文字である。つまり、URIには日本語の文字を直接入れられない(2進数によって広がるデジタルデータ表現の基礎知識5選参照)。
%エンコーディング
%エンコーディング(%-Encoding)とは、日本語などURI仕様が許可していない文字をURIに入れるためのしくみである。%エンコーディングでは、UTF-8の文字を構成するバイトそれぞれを「%xx」(xxは16進数)で記述して、URIに使用できない文字を表現する。例えば「あ」は「%E3%81%82」と表される。
%エンコーディングの文字エンコーディング
UTF-8以外の文字エンコーディングを使ったURIが利用されている場合、一般的には元となるフォームを提供しているWebページの文字エンコーディングを使うことで解決する。ただし、現代的なWebサイトの多くはUTF-8を採用しているため、URIをUTF-8で%エンコードする場合がほとんどである。
5 URIの長さ制限
仕様上はURIの長さに制限はない。しかし、実装上は制限が存在する。特にInternet Explorerはバージョンを問わず2,038バイトまでという制限があるため、事実上この長さに合わせて実装することが多くなる。
6 様々なスキーム
URIスキームの公式な一覧はIANA(Internet Assigned Numbers Authority)にあり、70弱が登録されている。非公式も含めたURIスキームは100以上存在する。
7 URIの実装で気をつけること
URIの実装で気をつけることは、相対URIの解決と%エンコーディングの扱いの2点である。クライアントで相対URIを解決するには面倒な処理が必要なため、なるべく絶対URIを使う方が親切である。また、%エンコーディングの文字エンコーディングとしては、なるべくUTF-8を用いるのが望ましい。
最後に
URIには、URIスキームやホスト名といった構文、使用できる文字、そして長さ制限といった仕様がある。URIの実装で気をつけることは、なるべく絶対URIとUTF-8を使うことである。使いやすいWebサービスとWeb APIを設計するためにも、URIの仕様については理解しておきたい。
次回は、「クールなURIは変わらない」と言われるURIの設計について説明する。
![]() |