SOAPでwebAPIを叩く
仕事でちょっと必要になったので、PHPのSOAP拡張モジュールを使ってみた。わかってしまえばなんということはないのだが、意外と資料が見当たらなかったので手順をメモしておく。
SOAPって何だ?
Simple Object Access Protocol
とくちょう:
通信プロトコル : HTTP
SOAP 1.0 : HTTPのみ
SOAP 1.1~ : FTP、SMTPなども選択できる
(現行バージョンは1.2)
データフォーマット : XML
「エンベロープ」というメタデータでくるむ
文書本体(Body)の前にヘッダ(Header)をつけることができる(=Optional)
PHPでSOAP
PHP5からSOAPの拡張モジュールは標準添付になっているが、ビルドオプションで利用を宣言する必要がある。
今回の目標
PHPによるwebアプリがクライアントになり、とあるサーバのサービスをSOAPで叩いて利用する。
インストール
configureオプションに「–enable-soap」を指定してビルド。
設定
パラメータの意味とデフォルトはこの辺に。今回はとりあえずなにも指定しない(=デフォルト値が使用される)状態で。
WSDL
WSDLとは?
Web Services Description Language
データの名前と型、サーバとやり取りするメッセージ、サービスの定義などのメタデータを記述したもの。サーバサイドでSOAPサービスを提供する場合は作成する必要があるが、既存のサービスを利用する場合は提供者が用意しているWSDLファイルを使えばいい。今回の案件でも用意されていた。
そのうち必要になりそうなので、この調査をしたときにヒットしたサイトもLinksにメモっておく。
実際のコード
「すでに提供されているAPIをPHPから使う」場合のサンプルがあまり見当たらなかったので、ここでは「要求されているSOAPメッセージ(XML)を生成するには」というアプローチで書いてみる。
サンプルXML
APIが「この機能を使うにはこんなSOAPメッセージを送れ」というXMLをサンプルとして公開している、と仮定する(…というか今回の案件では仕様書に書いてあった)。
<?xml version="1.0" encoding="UTF-8"?> <env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:ns1="http://www.example.com/SomeProcess"> <env:Header> <ns1:AuthHeader> <ns1:Username>USERNAME</ns1:Username> <ns1:Password>PASSWORD</ns1:Password> </ns1:AuthHeader> </env:Header> <env:Body> <ns1:CreateSomeProcessRequest> <ns1:request> <ns1:SomeType>foo</ns1:SomeType> <ns1:SomeParam>bar</ns1:SomeParam> <ns1:SomeDetail>some parameter example</ns1:SomeDetail> <ns1:Entries> <ns1:SomeProcessRequestEntry> <ns1:Shortname>hoge</ns1:Shortname> <ns1:Url>http://www.exapmle.net/hoge</ns1:Url> <ns1:flag>true</ns1:flag> </ns1:SomeProcessRequestEntry> <ns1:SomeProcessRequestEntry> <ns1:Shortname>piyo</ns1:Shortname> <ns1:Url>http://www.exapmle.jp/piyo</ns1:Url> <ns1:flag>false</ns1:flag> </ns1:SomeProcessRequestEntry> </ns1:Entries> </ns1:request> </ns1:CreateSomeProcessRequest> </env:Body> </env:Envelope>
サンプルコード
こんなコードでメッセージが生成できる。SOAPメッセージとの対比に気をつければ使い方が把握できると思う。
<?php class SoapSample
{
public function doSoapRequest()
{
// SoapClientの生成 $this->soap_client = new SoapClient(
'http://www.example.com/path/to/wsdl_file.wsdl',
array(
'soap_version' => SOAP_1_2,
'trace' => 1, // リクエスト / レスポンスのヘッダ / 本文を取得するために必要 ) ) ; // 認証用ヘッダを生成して付与 $soap_header = array(
'http://www.exapmple.com/SomeProcess', // 名前空間 'AuthHeader', // 要素名 array( // パラメータの配列(SoapVar) 'Username' => new SoapVar('USERNAME', XSD_STRING),
'Password' => new SoapVar('PASSWORD', XSD_STRING),
)
) ;
$this->soap_client->__setSoapHeaders($soap_header) ;
// リクエストパラメータを生成 $soap_param = array(
'request' => array(
'SomeType' => 'foo',
'SomeParam' => 'bar',
'SomeDetail' => 'some parameter example',
'Entries' => array(
array(
'Shortname' => 'hoge',
'Url' => 'http://www.exapmle.net/hoge',
'flag' => true,
)
array(
'Shortname' => 'piyo',
'Url' => 'http://www.exapmle.jp/piyo',
'flag' => false,
)
)
)
) ;
// リクエストを行う try { $this->soap_client->CreateSomeProcessRequest($soap_params) ;
}
catch (Exception $e)
{
echo $e ;
}
}
}
?>
リクエストとレスポンス
リクエスト / レスポンスのヘッダ / 本文はそれぞれSoapClientクラスのメソッドで取得できる。
- public string __getLastRequest ( void )
- public string __getLastRequestHeaders ( void )
- public string __getLastResponse ( void )
- public string __getLastResponseHeaders ( void )
レスポンスも当然XMLで返ってくるので、適当なライブラリでパーズして使う。
エラー処理
何らかの理由でエラーが発生した場合、以下のような構造のXMLが返ってくる。ざっくり要約すると「soap:Bodyにsoap:Faultメッセージが含まれていたらエラー」ということである。
<?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <soap:Body> <soap:Fault> <soap:Code> <soap:Value>soap:Receiver</soap:Value> </soap:Code> <soap:Reason> <soap:Text xml:lang="en">Server was unable to process request. ---> Exception thrown by Authenticator.AuthenticateUser method. Authentication failed. The Username and/or Password are invalid. Please enter a valid Username and Password</soap:Text> </soap:Reason> <soap:Detail /> </soap:Fault> </soap:Body> </soap:Envelope>
soap:Faultメッセージの存在をチェックしてエラー処理をするとよいだろう。
まとめ
駆け足かつちょうざっくりの説明だが、とりあえずこれでクライアントとしてPHPからSOAPのwebAPIを叩くことはできるようになった。もしかしたらSOAPサーバもやるかもしれないが、予定は未定。
Links
Glossary
http://ja.wikipedia.org/wiki/SOAP_(%E3%83%97%E3%83%AD%E3%83%88%E3%82%B3%E3%83%AB)
●SOAPとは 【Simple Object Access Protocol】 – 意味/解説/説明/定義 : IT用語辞典
●WSDLとは 【Web Services Description Language】 – 意味/解説/説明/定義 : IT用語辞典
SOAP on PHP
http://www.php.net/manual/ja/ref.soap.php
●PHP5でSOAPを用いたブックマークサービスを作成する:CodeZine
http://codezine.jp/article/detail/199
●PHP5を試してみる – SOAP extension+Google Web APIsでGoogle検索してみる – Do You PHP?
http://www.doyouphp.jp/php5/php5_soap_extension_google.shtml