wsdlsoaptutorialweb-services

WSDL ファイルの読み方: 開発者のためのビジュアルガイド

SOAPless Team12 min read

WSDL ファイルは SOAP サービスの設計図です。クライアントがサービスと通信するために必要な情報 — 利用可能なオペレーション、送信すべきデータ、返ってくるデータ、リクエスト先のアドレス — がすべて定義されています。

問題は、WSDL が非常に読みにくいことです。1つの WSDL が数百行の XML に及び、深くネストされたスキーマ、複数の名前空間、要素間の相互参照が絡み合います。多くの開発者は WSDL を無視して自動生成コードに頼るか、XML を何時間も睨んでサービスの動作を理解しようとしています。

このガイドでは、WSDL を体系的に読む方法を解説します。5 つのコア要素とその接続関係を理解すれば、どんな WSDL でも読み解けるようになります。

WSDL 1.1 の 5 大要素

すべての WSDL 1.1 ドキュメントは、特定の順序で接続された 5 つの要素から構成されています:

┌─────────────────────────────────────────────────┐
│  <wsdl:definitions>                             │
│                                                 │
│  ┌─────────┐                                    │
│  │  types  │  XSD スキーマ — データ構造の定義    │
│  └────┬────┘                                    │
│       ↓                                         │
│  ┌─────────┐                                    │
│  │ message │  型付きパーツの名前付きグループ     │
│  └────┬────┘                                    │
│       ↓                                         │
│  ┌──────────┐                                   │
│  │ portType │  抽象的なオペレーション定義        │
│  └────┬─────┘                                   │
│       ↓                                         │
│  ┌─────────┐                                    │
│  │ binding │  具体的なプロトコル詳細             │
│  └────┬────┘                                    │
│       ↓                                         │
│  ┌─────────┐                                    │
│  │ service │  ネットワークアドレス (エンドポイント) │
│  └─────────┘                                    │
│                                                 │
└─────────────────────────────────────────────────┘

スタック構造として考えてください。各層は上の層に依存しています。service が「どこに送るか」、binding が「どう送るか」、portType が「何を呼ぶか」、message が「どんなデータを送るか」、types が「データの形」を定義します。

完全な WSDL の例

天気予報サービスの WSDL を使って、各要素を解説します。このサービスには GetCurrentWeatherGetForecast の 2 つのオペレーションがあります。

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions
  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:tns="http://example.com/weatherservice"
  targetNamespace="http://example.com/weatherservice"
  name="WeatherService">

  <!-- ==================== -->
  <!-- 1. TYPES             -->
  <!-- ==================== -->
  <wsdl:types>
    <xsd:schema targetNamespace="http://example.com/weatherservice">

      <xsd:element name="GetCurrentWeather">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element name="city" type="xsd:string"/>
            <xsd:element name="countryCode" type="xsd:string"
                         minOccurs="0"/>
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>

      <xsd:element name="GetCurrentWeatherResponse">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element name="temperature" type="xsd:decimal"/>
            <xsd:element name="unit" type="xsd:string"/>
            <xsd:element name="condition" type="xsd:string"/>
            <xsd:element name="humidity" type="xsd:int"/>
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>

      <xsd:element name="GetForecast">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element name="city" type="xsd:string"/>
            <xsd:element name="days" type="xsd:int"/>
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>

      <xsd:element name="GetForecastResponse">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element name="forecasts" type="tns:ForecastDay"
                         maxOccurs="unbounded"/>
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>

      <xsd:complexType name="ForecastDay">
        <xsd:sequence>
          <xsd:element name="date" type="xsd:date"/>
          <xsd:element name="high" type="xsd:decimal"/>
          <xsd:element name="low" type="xsd:decimal"/>
          <xsd:element name="condition" type="xsd:string"/>
        </xsd:sequence>
      </xsd:complexType>

    </xsd:schema>
  </wsdl:types>

  <!-- ==================== -->
  <!-- 2. MESSAGES           -->
  <!-- ==================== -->
  <wsdl:message name="GetCurrentWeatherRequest">
    <wsdl:part name="parameters" element="tns:GetCurrentWeather"/>
  </wsdl:message>

  <wsdl:message name="GetCurrentWeatherResponse">
    <wsdl:part name="parameters"
               element="tns:GetCurrentWeatherResponse"/>
  </wsdl:message>

  <wsdl:message name="GetForecastRequest">
    <wsdl:part name="parameters" element="tns:GetForecast"/>
  </wsdl:message>

  <wsdl:message name="GetForecastResponse">
    <wsdl:part name="parameters" element="tns:GetForecastResponse"/>
  </wsdl:message>

  <!-- ==================== -->
  <!-- 3. PORT TYPE          -->
  <!-- ==================== -->
  <wsdl:portType name="WeatherServicePortType">
    <wsdl:operation name="GetCurrentWeather">
      <wsdl:input message="tns:GetCurrentWeatherRequest"/>
      <wsdl:output message="tns:GetCurrentWeatherResponse"/>
    </wsdl:operation>
    <wsdl:operation name="GetForecast">
      <wsdl:input message="tns:GetForecastRequest"/>
      <wsdl:output message="tns:GetForecastResponse"/>
    </wsdl:operation>
  </wsdl:portType>

  <!-- ==================== -->
  <!-- 4. BINDING            -->
  <!-- ==================== -->
  <wsdl:binding name="WeatherServiceSoapBinding"
                type="tns:WeatherServicePortType">
    <soap:binding style="document"
                  transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="GetCurrentWeather">
      <soap:operation
        soapAction="http://example.com/weatherservice/GetCurrentWeather"/>
      <wsdl:input><soap:body use="literal"/></wsdl:input>
      <wsdl:output><soap:body use="literal"/></wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="GetForecast">
      <soap:operation
        soapAction="http://example.com/weatherservice/GetForecast"/>
      <wsdl:input><soap:body use="literal"/></wsdl:input>
      <wsdl:output><soap:body use="literal"/></wsdl:output>
    </wsdl:operation>
  </wsdl:binding>

  <!-- ==================== -->
  <!-- 5. SERVICE            -->
  <!-- ==================== -->
  <wsdl:service name="WeatherService">
    <wsdl:port name="WeatherServicePort"
               binding="tns:WeatherServiceSoapBinding">
      <soap:address location="https://weather.example.com/soap"/>
    </wsdl:port>
  </wsdl:service>

</wsdl:definitions>

各セクションを詳しく見ていきましょう。

1. Types: データ辞書

<wsdl:types> セクションには、サービスで使用されるすべてのデータ構造を定義する XSD (XML Schema Definition) スキーマが含まれます。TypeScript の interface や JSON Schema に相当する部分です。

主要な XSD の構成要素:

XSD 構文意味
xsd:element名前付きデータフィールド<xsd:element name="city" type="xsd:string"/>
xsd:complexType複数フィールドを持つ構造体クラスやインターフェースに相当
xsd:sequenceフィールドの出現順序要素の順序付きリスト
xsd:string文字列"Tokyo"
xsd:int整数42
xsd:decimal小数23.5
xsd:dateISO 日付2025-09-19
xsd:boolean真偽値true
minOccurs="0"フィールドは省略可能任意項目
maxOccurs="unbounded"フィールドは配列繰り返し要素

GetCurrentWeather 要素を読むと、「このオペレーションは必須の city (文字列) と省略可能な countryCode (文字列) を受け取る」ことがわかります。

2. Message: 名前付きパラメータグループ

<wsdl:message> 要素は、型付きパーツを名前付きの単位にグループ化します。各メッセージは types セクションで定義された要素を参照します。

<wsdl:message name="GetCurrentWeatherRequest">
  <wsdl:part name="parameters" element="tns:GetCurrentWeather"/>
</wsdl:message>

これは「GetCurrentWeather のリクエストメッセージは、GetCurrentWeather 要素をパラメータとして使用する」という意味です。

document/literal スタイル (最も一般的) では、各メッセージは通常 1 つのパートを持ち、1 つの要素を指します。rpc/encoded スタイル (古い形式) では、複数のパートが明示的な型を持つことがあります。

3. PortType: インターフェース契約

<wsdl:portType> は抽象的なオペレーションを定義します。本質的には API のメソッドシグネチャです。サービスが何をできるかを理解するための最も重要なセクションです。

<wsdl:portType name="WeatherServicePortType">
  <wsdl:operation name="GetCurrentWeather">
    <wsdl:input message="tns:GetCurrentWeatherRequest"/>
    <wsdl:output message="tns:GetCurrentWeatherResponse"/>
  </wsdl:operation>
</wsdl:portType>

読み方:「WeatherServicePortType インターフェースには GetCurrentWeather というオペレーションがあり、GetCurrentWeatherRequest メッセージを受け取り、GetCurrentWeatherResponse メッセージを返す」

オペレーションには <wsdl:fault> 要素でエラーレスポンスを定義することもできます。

4. Binding: プロトコルの詳細

<wsdl:binding> は、抽象的なオペレーションを具体的なプロトコルにマッピングする方法を指定します。SOAP サービスでは、SOAP バージョン、エンコーディングスタイル、トランスポートプロトコル、SOAPAction ヘッダーが定義されます。

binding の主要な属性:

属性意味
styledocument または rpcBody の構造方法
transporthttp://schemas.xmlsoap.org/soap/httpHTTP トランスポート
useliteral または encoded型のシリアライズ方法
soapActionURI 文字列SOAPAction HTTP ヘッダーの値

最も一般的な組み合わせは document/literal です。Body にスキーマに正確に一致する XML ドキュメントが含まれます。古いサービスでは rpc/encoded が使われることがあり、パラメータのラッピング方法が異なります。

5. Service: エンドポイントアドレス

<wsdl:service> 要素はすべてを結びつけ、サービスの所在を指定します:

<wsdl:service name="WeatherService">
  <wsdl:port name="WeatherServicePort"
             binding="tns:WeatherServiceSoapBinding">
    <soap:address location="https://weather.example.com/soap"/>
  </wsdl:port>
</wsdl:service>

soap:address location が HTTP リクエストの送信先 URL です。1 つのサービスが複数のポート (例: SOAP 1.1 用と SOAP 1.2 用) を持つこともあります。

SOAP 1.1 vs 1.2 の Binding の違い

WSDL が SOAP 1.2 をサポートしている場合、binding セクションで異なる名前空間が使われます:

<!-- SOAP 1.1 -->
<soap:binding xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
              style="document"
              transport="http://schemas.xmlsoap.org/soap/http"/>

<!-- SOAP 1.2 -->
<soap12:binding xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
                style="document"
                transport="http://schemas.xmlsoap.org/soap/http"/>
項目SOAP 1.1SOAP 1.2
名前空間http://schemas.xmlsoap.org/soap/envelope/http://www.w3.org/2003/05/soap-envelope
Content-Typetext/xml; charset=utf-8application/soap+xml; charset=utf-8
SOAPActionHTTP ヘッダーContent-Type の action パラメータ
Fault コードClientServerSenderReceiver

名前空間の読み方

名前空間は、JSON ベースの API から WSDL に入った開発者にとって最も混乱する部分です。よく見かける名前空間の一覧を示します:

接頭辞URI用途
wsdlhttp://schemas.xmlsoap.org/wsdl/WSDL 構造要素
soaphttp://schemas.xmlsoap.org/wsdl/soap/SOAP 1.1 バインディング拡張
xsdhttp://www.w3.org/2001/XMLSchemaXML Schema 型
tns(サービスごとに異なる)"This namespace" — サービス自身の名前空間

targetNamespace はサービスの一意な識別子です。tns:GetCurrentWeather と記述されている場合、ターゲット名前空間内の GetCurrentWeather 要素を参照しています。

WSDL の読み方: ボトムアップ戦略

WSDL を初めて開いたときは、ボトムアップで読むことをお勧めします:

  1. <wsdl:service> から始める — エンドポイント URL とポート名を確認
  2. binding を辿る — SOAP バージョン、スタイル、SOAPAction 値をチェック
  3. portType を読む — 利用可能なオペレーションと入出力メッセージを一覧化
  4. message から types を追跡 — 各オペレーションが期待するデータと返すデータを理解
  5. XSD の型を調査 — 完全なデータモデルをマッピング

このボトムアップアプローチが効率的な理由は、具体的な情報 (リクエスト送信先) から始めて抽象的な詳細 (データスキーマ) へ向かうためです。

WSDL 調査に役立つツール

ツール種別用途
SoapUIデスクトップアプリWSDL の完全なテスト、リクエスト生成
WizdlerChrome 拡張機能オペレーションの素早い確認
curlコマンドライン生の SOAP リクエストテスト
Visual StudioIDEWCF クライアント生成 (.NET)
wsimportCLIJava クライアント生成

SoapUI は特に便利です。WSDL をパースして全オペレーションのサンプルリクエストを自動生成するため、すぐに実行可能な出発点を得られます。Qiita や Zenn でも SoapUI の使い方に関する記事が多く、日本語の情報も豊富です。

SOAPless による解決

WSDL を読むスキルは重要ですが、SOAP サービスと連携するたびにそのスキルを発揮する必要はありません。SOAPless は WSDL を自動でパースします。WSDL URL を貼り付けるだけで、すべてのオペレーション、データ型、バインディングが手動の XML 調査なしに抽出されます。

各オペレーションは OpenAPI 3.0 仕様付きの REST エンドポイントに変換されます。メッセージから型を追跡して XML エンベロープを手組みする代わりに、JSON を送って JSON を受け取るだけです。ダッシュボードからオペレーションをインタラクティブにテストできるため、コードを書いたり WSDL を 1 行も読んだりせずに、SOAP サービスの機能を探索できます。

複数の SOAP サービスと連携する必要があるチームにとって、WSDL パース、エンベロープ構築、名前空間デバッグの繰り返しサイクルが不要になります。