Edited at

正しい知識としてのSOAP

More than 1 year has passed since last update.


SOAPってぶっちゃけなんなの?

よく説明されている言い方だと、Webサービスの一種で、RESTなどと比較されています。

しかしながら、実際に使用してみると、そのカテゴリ分けは非常に乱暴で大雑把だと感じます。

ざっくり使い方を見て説明してみましょう。

SOAPの使い方一例(クライアント側)


  • プロジェクトに SOAPサーバーのWSDLというサービス定義用のXMLを返すURIを登録します。(WSDLはUPnPなどネットワークデバイスにも使用されています)

  • IDE(EclipseやVisualStudio)はWSDLからAPIを読み取り、裏でそのサービスをクラスオブジェクトとして定義してくれます。

  • ユーザーは普通のクラスライブラリと同じように利用できます。

//Webサービスを初期化

SOAPSample objSoap = new SOAPSample();

//APIを使う
objSoap.setHoge( 100, "あひゃ" ); //登録系

String name = objSoap.getHoge( 100 ); //読み込み系

SOAPサービスの建て方の一例(サーバ側)

これはJavaのSOAPサーバーの代表的なソフトウェア「AXIS2」のイメージで書いています。


  • プロジェクトにSOAPライブラリを追加します。

  • SOAPライブラリをオーバーライドしたクラスを作り、その中に普通に関数を書きます。
    (その関数が自動でAPIメソッドになる)

  • コンパイルしたバイナリファイルをSOAPサーバのモジュールフォルダに放り込みます。

  • SOAPサーバーを起動します。

  • おしまい。


じゃあRESTってなんなのさ?

最近はRESTとか言わなくなってきましたが、RESTはプロトコルや手続きを自前で書いてHTTP通信のPOSTなどを利用してデータのやり取りを行うものです。

よくある、POSTメソッドを使ってJSONを受け取ったりする、アイツです。

昔CGIでjavascript型のハッシュ定義をテキストで返してevalで受け取る 的なものを書いてた方は、え?!と思うかもしれません。

あなたは知らないうちにRESTを使っていたのです。(私も知らないでそういうことしてた)

なんか比較される筋合いなくね?!!

私はRESTの説明文を読んだ瞬間にそう叫びました。あんな便利なSOAPを作った人たちに申し訳ない。そんな気持ちになる。


設計思想の違い

SOAPとRESTの一番の違いは、最初の設計思想が SOAP=同期通信バンザイ、REST=非同期バンザイであったところかもしれません。


C#でSOAP関数を同期呼出

SoapApp objSoap = new SoapApp();

String result = objSoap.getTopSalesShopList(DateTime.Now.toString("yyyy-MM-dd"));
this.setServMsg(result);

非常にシンプル。

しかし、非同期でやろうとすると、Ajaxのような無名コールバック関数を使うことができないのでこんなふうになる。


C#でSOAP関数を非同期で呼ぶ例

SoapApp objSoap = new SoapApp();

///コールバック関数定義
objSoap.getTopSalesShopListCompleted += ((getTopSalesShopListCompletedEventHandler)
delegate(object sender, getTopSalesShopListCompletedEventArgs e)
{
this.setServMsg(e.Result);
});
///非同期呼出
objSoap.getTopSalesShopListAsync(DateTime.Now.toString("yyyy-MM-dd"));

IDEがいろいろお世話して各API関数毎に非同期用のクラスを作ってくれたらしい。

解説すると、

コールバック関数の定義名が「<関数名>CompletedEventHandler」となっていて

それをデリゲート関数にして、イベントハンドラの「<関数名>Completed」に突っ込む

これで準備完了。

あとは非同期専用にカプセル化された「<関数名>Async」を呼び出す。

すると、完了時にデリゲート関数が呼び出される仕組み。

これは地味に面倒で、可読性も非常に悪い。本来お手軽なはずのSOAPの取り回しを不便にさせてしまっている。

なのでIDEには悪いけど、私は可読性のためにこっちを使っている


System.Threading.Threadを使ってシンプルに書く方法

Thread thread = new Thread(

delegate()
{
SoapApp objSoap = new SoapApp();
String result = objSoap.getTopSalesShopList(DateTime.Now.toString("yyyy-MM-dd"));
this.setServMsg(result);
}
);
thread.Start();


SOAPがあまり使われなくなった原因

あくまで憶測です。


  • SOAPの内部プロトコルが、XMLで通信するのでデータ量が多い。(プリンタやルータが使ってるUPnPだってXMLじゃん!)

  • オブジェクトが使われるたびにソケットが大量に作成されるのでサーバー負荷がかかる?(らしい)

  • 当初XMLによる容易な手続きを実装していなかった、Javascriptと相性が悪かった。

  • SOAPは利用するのにライブラリが必要なこともあって、「なんか難しそう」というイメージがあった。

  • Googleが使わなかった。(代わりに独自のサービスをGoogle API として公開していたが、それがいわゆるRESTだった)

  • Webサービス ≒ Web API ≒ REST という認識が定着していった。

こんな感じだと思っています。


まとめ

サーバー内のモジュールに関数を定義するだけでクラスライブラリのように利用できるSOAPは、通信量をそこまで気にすることのない、業務向けのGUIアプリなどの開発に適していると思います。

SOAPは確かにプロトコルレベルで考えると、冗長なXMLを採用していることから敬遠されがちですが、ケースによっては非常に強力な助っ人になるものです。

「もはや古い技術だ」「一般的じゃない」と頭ごなしに切り捨てず、よくよくSOAPの利便性を理解して見直して欲しいと思うのです。