連載 [第1回] :
PerlでWeb APIを使いたおすWeb APIの紹介
2006年9月27日(水)
XML-RPCの仕組み
この記事では、Web APIの標準的な仕様としてよく利用されているものをいくつか取り上げ、その仕組みや利用方法を紹介していくことにします。まずはXML-RPCです。
XML-RPCは、名前を見てもわかるとおり、データとしてXMLを利用するWeb APIの仕様です。RPCはRemote Procedure Callの略です。XMLを利用して、ネットワーク越しにプロシージャ、つまり何らかの処理を呼び出すものである、という仕組みをそのまま名前にしています。
XML-RPCは、米Userland社が1998年に自社のWebサイト管理ツールであるFrontierで利用するために策定した仕様であり、策定者は当時Userland社の社長を務めていたDave Winer氏です。Winer氏はRSS 0.91やRSS 2.0の仕様策定にも関わった人としても有名です。
XML-RPCは比較的古くからある仕様ではありますが、シンプルで使いやすいので、現在でも利用されています。例えばブログのサービス/ツールであるBloggerやMovable Typeなどは、ブログの記事を取得したり更新するためのAPIとして採用しています。
まずはXML-RPCの仕様を簡単に見ていくことにしましょう。XML-RPCを利用したAPIでは、アクセスするためのエントリポイントとなるURLが用意されています。このURLに対してアクセスすることで、処理を実行するわけです。
XML-RPCでは1つのエントリポイントを使って複数のメソッドを提供できます。アクセスの際にはメソッド名とパラメータを渡します。パラメータは文字列や数値、配列など、プログラムにおける通常のサブルーチン呼び出しと同じようなものが利用できます(当たり前ですが異なるコンピュータ上で処理を行うので、メモリ参照を渡すことはできません)。すると処理の結果を戻り値として取得できます。戻り値としては複数の値をとることはできないというルールになっていますが、実際には戻り値を配列にすることで、複数の値(例えばブログのエントリのURLとタイトル、コンテンツなど)を返すこともできます。
クライアントからサーバーへのアクセスには、HTTPのPOSTメソッドを利用します。送受信する情報はXMLで、リクエストとレスポンスにおけるボディとして送受信されます。まずはリクエストのサンプルをリスト3に示します。
リスト3:XML-RPCのリクエストサンプル
POST /RPC2 HTTP/1.0
User-Agent: ExampleClient/1.0
Host: api.example.com
Content-Type: text/xml
Content-length: 255
<?xml version="1.0"?>
<methodCall>
<methodName>example.getUser</methodName>
<params>
<param>
<value><i4>23456</i4></value>
</param>
<param>
<value><boolean>1</boolean></value>
</param>
</params>
</methodCall>
このサンプルはヘッダーとボディをすべて含むリクエストの全データです。リクエストヘッダーにおいては、「User-Agent」、「Host」、「Content-Type」、「Content-Length」が必須ということになっています。Content-Typeは「text/xml」です。
実際のデータは簡単な構造なので、見ればだいたい察しがつくのではないでしょうか。データ全体はmethodCallというルート要素になっており、その中にメソッド名を示すmethodNameと渡すパラメータを示すparams、そしてその中にはデータをあらわすvalue要素が入ります。
value要素に指定できる値はさまざまで、その値の種類ごとに要素が定義されています。例えば文字列ならstring、真偽値ならbooleanといった具合です(型の指定を省略するとstringとみなされます)。利用可能なデータ型を表1に示します。
型 | 種類 |
---|---|
i4、int | 4バイト符号付き整数 |
boolean | 真偽値(1が真、0が偽) |
string | 文字列 |
double | 倍精度浮動小数 |
dateTime.iso8601 | 日付と時刻(ISO-8601形式) |
base64 | BASE64エンコードされたバイナリ |
array | 配列 |
struct | 構造体 |
配列を表すarrayと、構造体(ハッシュのような名前とデータの組)を表すstructが複数の値を持つデータ型で、それ以外は単一のデータを表します。バイナリデータを送受信する際にはBASE64でエンコードすることになります。
リスト4にarrayとstructのサンプルを示します。
リスト4:arrayとstructのサンプル
◆array
<array>
<data>
<value><string>apple</syring></value>
<value><i4>40</i4></value>
<value><boolean>1</boolean></value>
</data>
</array>
◆struct
<struct>
<member>
<name>userid</name>
<value><i4>2342</i4></value>
</member>
<member>
<name>username</name>
<value><string>Taro Yamada</string></value>
</member>
</struct>
arrayは単にvalueが列挙されるだけですが、structはmemberという要素を用いて、複数のデータを列挙します。データ名はname要素に、実際のデータはvalue要素に入ります。
どちらも異なるデータ型のデータをまとめることができ、arrayやstructの中にarrayやstructを内包させることも可能です。なお、struct型ではmemberの順番は保持されません。
さて、送信したリクエストが正しく処理がされれば、サーバーからXMLを使ったレスポンスデータが返ってきます(リスト5)。
リスト5:レスポンスデータの例
HTTP/1.1 200 OK
Content-Length: 163
Content-Type: text/xml
<?xml version="1.0"?>
<methodResponse>
<params>
<param>
<value><string>Taro Yamada</string></value>
</param>
</params>
</methodResponse>
レスポンスデータの場合は、ルート要素がmethodResponseになります。その中には1つのparams要素があり、その中に1つのparam要素が含まれます。ここに2つ以上param要素を入れることはできません。しかしarrayやstructを返すことで、複数の値を返すことは可能です。
もし、サーバーが処理をした際にエラーが発生した場合は、paramsの代わりにfault要素を入れることになっています(リスト6)。
リスト6:エラーレスポンスデータの例
HTTP/1.1 200 OK
Content-Length: 426
Content-Type: text/xml
<?xml version="1.0"?>
<methodResponse>
<fault>
<value>
<struct>
<member>
<name>faultCode</name>
<value><int>4</int></value>
</member>
<member>
<name>faultString</name>
<value><string>Too many parameters.</string></value>
</member>
</struct>
</value>
</fault>
</methodResponse>
エラーの場合でも、XML-RPCの処理中で発生したエラーであれば、ステータスコードは200になります。faultの場合は、データとしてはstruct型を返し、そこに含まれる要素はエラーコードを示すfaultCodeと、エラーの内容を示すfaultStringを含めることが決められています。
これがXML-RPCの仕様になります。かなりシンプルな仕様だなあ、という印象ではないでしょうか。XML-RPCが規定するのは、サブルーチンを利用することに置き換えれば、パラメータを渡して呼び出す部分と、戻り値を受け取る部分にすぎません。XML-RPCでは、それに必要な最低限のルールを規定しているのにすぎないのです。
連載バックナンバー
Think ITメルマガ会員登録受付中
Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。