Practical SOAP Consumption Examples

Learn to integrate SOAP services in different languages

πŸ“¨ Manual SOAP Request

Sometimes it's necessary to build the SOAP request manually.

HTTP Structure

POST /service HTTP/1.1
Host: example.com
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://example.com/MyOperation"
Content-Length: [size]

<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope 
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:ex="http://example.com/schema">
  <soapenv:Header>
    <!-- Optional headers -->
    <soapenv:AuthHeader>
      <soapenv:Username>testuser</soapenv:Username>
      <soapenv:Password>testpass</soapenv:Password>
    </soapenv:AuthHeader>
  </soapenv:Header>
  <soapenv:Body>
    <ex:MyOperation>
    <ex:param1>abc</ex:param1>
    <ex:param2>123</ex:param2>
    </ex:MyOperation>
  </soapenv:Body>
</soapenv:Envelope>
        

With cURL


          curl -X POST \
  https://example.com/service \
  -H Content-Type: text/xml; charset=utf-8 \
  -H SOAPAction: "http://example.com/MyOperation" \
  -d <?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ex="http://example.com/schema">
  <soapenv:Body>
    <ex:MyOperation>
    <ex:param1>abc</ex:param1>
    <ex:param2>123</ex:param2>
    </ex:MyOperation>
  </soapenv:Body>
</soapenv:Envelope>
      

Advertisement space

🐍 Python with Zeep

Zeep is the most modern and robust library for SOAP in Python.

Installation and Basic Usage

# Installation
pip install zeep

# Basic usage

from zeep import Client
import zeep

# Create client from WSDL
client = Client("https://example.com/service?wsdl")

# List available operations
print(client.service.__dict__.keys())

# Call operation
result = client.service.MyOperation(param1="abc", param2=123)
print(result)

Advanced Configurations


          from zeep import Client, Settings
from zeep.transports import Transport
from requests import Session
import ssl

# Configure custom HTTP session
session = Session()
session.verify = False  # For self-signed certificates
session.auth = ("username", "password")  # Basic authentication

# Configure transport
transport = Transport(session=session)

# Zeep settings
settings = Settings(strict=False, xml_huge_tree=True)

# Client with configurations
client = Client("https://example.com/service?wsdl", 
    transport=transport, 
    settings=settings)

# Operation with custom SOAP headers
header = {"Authentication": {"Token": "my-token"}}
result = client.service.MyOperation(
    param1="abc", 
    param2=123,
    _soapheaders=header
)

Advertisement space

β˜• Java with JAX-WS

JAX-WS is the Java standard for SOAP web services.

Class Generation

# Generate classes from WSDL
wsimport -keep -p com.example.ws https://example.com/service?wsdl

# Or using Maven
mvn jaxws:wsimport

Maven Configuration

<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>jaxws-maven-plugin</artifactId>
  <version>2.6</version>
  <executions>
    <execution>
      <goals>
        <goal>wsimport</goal>
      </goals>
      <configuration>
        <wsdlUrls>
          <wsdlUrl>https://example.com/service?wsdl</wsdlUrl>
        </wsdlUrls>
        <packageName>com.example.ws</packageName>
      </configuration>
    </execution>
  </executions>
</plugin>

Java Code

import com.example.ws.*;
import javax.xml.ws.BindingProvider;

public class SoapClient {
    public static void main(String[] args) {
      try {
        // Create service and port
        MyOperationService service = new MyOperationService();
        MyOperation port = service.getMyOperationPort();
      
        // Configure endpoint (optional)
        BindingProvider bp = (BindingProvider) port;
        bp.getRequestContext().put(
          BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
          "https://example.com/service"
        );
      
        // Configure timeout
        bp.getRequestContext().put(
        "com.sun.xml.ws.connect.timeout", 30000);
        bp.getRequestContext().put("com.sun.xml.ws.request.timeout", 60000);
        
        // Call operation
        String result = port.myOperation("abc", 123);
        System.out.println("Result: " + result);
      
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
}
      

Advertisement space

πŸ”· .NET with WCF

Windows Communication Foundation is the .NET technology for web services.

Generation with dotnet-svcutil

# Install tool
dotnet tool install --global dotnet-svcutil

# Generate client
dotnet-svcutil https://example.com/service?wsdl --outputDir ./Generated

# Or using Visual Studio: Add Service Reference

C# Code

using System;
using System.ServiceModel;
using System.Threading.Tasks;

class Program 
{
    static async Task Main(string[] args)
    {
      // Configure binding
      var binding = new BasicHttpBinding();
      binding.Security.Mode = BasicHttpSecurityMode.Transport;
      binding.MaxReceivedMessageSize = 10000;
      
      // Configure endpoint
      var endpoint = new EndpointAddress("https://example.com/service");
      
      // Create client
      var client = new MyOperationClient(binding, endpoint);
      
      try 
      {
        // Configure timeout
        client.InnerChannel.OperationTimeout = TimeSpan.FromSeconds(30);
        
        // Call operation
        var request = new MyOperationRequest 
        {
          param1 = "abc",
          param2 = 123
        };
        
        var response = await client.MyOperationAsync(request);
        Console.WriteLine($"Result: {response.result}");
      }
      catch (Exception ex)
      {
        Console.WriteLine($"Error: {ex.Message}");
      }
      finally
      {
        if (client.State == CommunicationState.Opened)
        client.Close();
      }
    }
}
      

Advertisement space

🟒 Node.js with node-soap

Popular library for consuming SOAP services in Node.js.

Installation and Usage

# Installation
npm install soap

// Basic usage
        

const soap = require("soap");

const url = "https://example.com/service?wsdl";

soap.createClient(url, (err, client) => {
  if (err) {
    console.error("Error creating client:", err);
    return;
  }
  
  // List available services
  console.log("Services:", Object.keys(client.describe()));
  
  // Call operation
  const args = {
    param1: "abc",
    param2: 123
  };
  
  client.MyOperation(args, (err, result) => {
    if (err) {
      console.error("Operation error:", err);
      return;
    }
    console.log("Result:", result);
  });
});

Version with Promises/Async

const soap = require("soap");
const { promisify } = require("util");

async function callSoap() {
  try {
    const client = await soap.createClientAsync(
      "https://example.com/service?wsdl"
    );
    
    // Configure headers if needed
    client.addSoapHeader({
      Authentication": {
      "Token": "my-token"
    }
    });
    
    // Configure basic security
    client.setSecurity(new soap.BasicAuthSecurity("user", "pass"));
    
    // Call operation
    const result = await client.MyOperationAsync({
      param1: "abc",
      param2: 123
    });
    
    console.log("Result:", result);
    
  } catch (error) {
    console.error("Error:", error);
  }
}

callSoap();
      

Advertisement space

🐘 PHP with SoapClient

PHP has native SOAP support through the SoapClient class.

<?php
try {
    // Client configurations
    $options = [
      "trace" => true,
      "exceptions" => true,
      "cache_wsdl" => WSDL_CACHE_NONE,
      "connection_timeout" => 30,
      "user_agent" => "PHP SOAP Client",
      "stream_context" => stream_context_create([
        "http" => [
          "timeout" => 60,
          "user_agent" => "PHP SOAP Client"
        ],
        "ssl" => [
          "verify_peer" => false,
          "verify_peer_name" => false
        ]
      ])
    ];
    
    // Create client
    $client = new SoapClient("https://example.com/service?wsdl", $options);
    
    // List available functions
    print_r($client->__getFunctions());
    
    // Call operation
    $params = [
      "param1" => "abc",
      "param2" => 123
    ];
    
    $result = $client->MyOperation($params);
    
    echo "Result: " . print_r($result, true);
    
    // Debug: see sent/received XML
    echo "Request XML:\n" . $client->__getLastRequest() . "\n";
    echo "Response XML:\n" . $client->__getLastResponse() . "\n";
    
} catch (SoapFault $e) {
    echo "SOAP Error: " . $e->getMessage() . "\n";
    echo "Code: " . $e->getCode() . "\n";
} catch (Exception $e) {
    echo "General Error: " . $e->getMessage() . "\n";
}
?>
      

🐹 Go with go-soap

Go doesn't have built-in SOAP support, but there are libraries available for SOAP communication.

Installation and Basic Usage

# Install the library
go get github.com/tiaguinho/gosoap

# Or using go mod
go mod init myproject
go get github.com/tiaguinho/gosoap

Go Implementation

package main

import (
    "encoding/xml"
    "fmt"
    "log"
    "github.com/tiaguinho/gosoap"
)

// Define request struct
type MyOperationRequest struct {
    XMLName xml.Name `xml:"ns:MyOperation"`
    Xmlns   string   `xml:"xmlns:ns,attr"`
    Param1  string   `xml:"ns:param1"`
    Param2  int      `xml:"ns:param2"`
}

// Define response struct
type MyOperationResponse struct {
    XMLName xml.Name `xml:"MyOperationResponse"`
    Result  string   `xml:"result"`
}

func main() {
    // Create SOAP client
    soap, err := gosoap.SoapClient("https://example.com/service?wsdl")
    if err != nil {
        log.Fatalf("Error creating SOAP client: %v", err)
    }
    
    // Set authentication if needed
    soap.SetHeaders(gosoap.HeaderParams{
        "Authorization": "Bearer token123",
    })
    
    // Create request
    request := MyOperationRequest{
        Xmlns:  "http://example.com/schema",
        Param1: "abc",
        Param2: 123,
    }
    
    // Call operation
    response, err := soap.Call("MyOperation", request)
    if err != nil {
        log.Fatalf("Error calling SOAP operation: %v", err)
    }
    
    // Parse response
    var result MyOperationResponse
    if err := response.Unmarshal(&result); err != nil {
        log.Fatalf("Error unmarshaling response: %v", err)
    }
    
    fmt.Printf("Result: %s\n", result.Result)
}

Manual HTTP Request Approach

package main

import (
    "bytes"
    "encoding/xml"
    "fmt"
    "io/ioutil"
    "net/http"
)

func callSOAPService() error {
    // Build SOAP envelope
    soapEnvelope := `<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
               xmlns:ex="http://example.com/schema">
    <soap:Header>
        <ex:Authentication>
            <ex:Token>my-token</ex:Token>
        </ex:Authentication>
    </soap:Header>
    <soap:Body>
        <ex:MyOperation>
            <ex:param1>abc</ex:param1>
            <ex:param2>123</ex:param2>
        </ex:MyOperation>
    </soap:Body>
</soap:Envelope>`

    // Create HTTP request
    req, err := http.NewRequest("POST", "https://example.com/service", 
                                bytes.NewBufferString(soapEnvelope))
    if err != nil {
        return fmt.Errorf("error creating request: %w", err)
    }
    
    // Set headers
    req.Header.Set("Content-Type", "text/xml; charset=utf-8")
    req.Header.Set("SOAPAction", "http://example.com/MyOperation")
    
    // Send request
    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        return fmt.Errorf("error sending request: %w", err)
    }
    defer resp.Body.Close()
    
    // Read response
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        return fmt.Errorf("error reading response: %w", err)
    }
    
    fmt.Printf("Response: %s\n", string(body))
    return nil
}

func main() {
    if err := callSOAPService(); err != nil {
        log.Fatal(err)
    }
}

πŸ¦€ Rust with savon

Rust provides SOAP support through community crates like savon or manual HTTP requests.

Cargo.toml Configuration

[dependencies]
reqwest = { version = "0.11", features = ["blocking"] }
serde = { version = "1.0", features = ["derive"] }
serde_xml_rs = "0.6"
tokio = { version = "1", features = ["full"] }
quick-xml = "0.30"

Rust Implementation

use reqwest::header::{HeaderMap, HeaderValue, CONTENT_TYPE};
use serde::{Deserialize, Serialize};
use std::error::Error;

#[derive(Debug, Serialize)]
#[serde(rename = "soap:Envelope")]
struct SoapEnvelope {
    #[serde(rename = "@xmlns:soap")]
    xmlns_soap: String,
    #[serde(rename = "@xmlns:ex")]
    xmlns_ex: String,
    #[serde(rename = "soap:Body")]
    body: SoapBody,
}

#[derive(Debug, Serialize)]
struct SoapBody {
    #[serde(rename = "ex:MyOperation")]
    operation: MyOperation,
}

#[derive(Debug, Serialize)]
struct MyOperation {
    #[serde(rename = "ex:param1")]
    param1: String,
    #[serde(rename = "ex:param2")]
    param2: i32,
}

#[derive(Debug, Deserialize)]
struct SoapResponse {
    #[serde(rename = "Body")]
    body: ResponseBody,
}

#[derive(Debug, Deserialize)]
struct ResponseBody {
    #[serde(rename = "MyOperationResponse")]
    response: MyOperationResponse,
}

#[derive(Debug, Deserialize)]
struct MyOperationResponse {
    result: String,
}

async fn call_soap_service() -> Result<(), Box> {
    // Build SOAP request
    let soap_body = r#"<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
               xmlns:ex="http://example.com/schema">
    <soap:Body>
        <ex:MyOperation>
            <ex:param1>abc</ex:param1>
            <ex:param2>123</ex:param2>
        </ex:MyOperation>
    </soap:Body>
</soap:Envelope>"#;

    // Create HTTP client
    let client = reqwest::Client::new();
    
    // Build headers
    let mut headers = HeaderMap::new();
    headers.insert(CONTENT_TYPE, HeaderValue::from_static("text/xml; charset=utf-8"));
    headers.insert("SOAPAction", HeaderValue::from_static("http://example.com/MyOperation"));
    
    // Send request
    let response = client
        .post("https://example.com/service")
        .headers(headers)
        .body(soap_body)
        .send() 
        .await?;
    
    // Check status
    if !response.status().is_success() {
        return Err(format!("Request failed with status: {}", response.status()).into());
    }
    
    // Parse response
    let response_text = response.text().await?;
    println!("Response: {}", response_text);
    
    // Deserialize if needed
    // let soap_response: SoapResponse = quick_xml::de::from_str(&response_text)?;
    // println!("Result: {:?}", soap_response.body.response.result);
    
    Ok(())
}

#[tokio::main]
async fn main() {
    match call_soap_service().await {
        Ok(_) => println!("SOAP call successful"),
        Err(e) => eprintln!("Error: {}", e),
    }
}

With Authentication

use reqwest::header::{HeaderMap, HeaderValue, AUTHORIZATION};

async fn call_soap_with_auth() -> Result<(), Box> {
    let client = reqwest::Client::builder()
        .timeout(std::time::Duration::from_secs(30))
        .build()?;
    
    let mut headers = HeaderMap::new();
    headers.insert(CONTENT_TYPE, HeaderValue::from_static("text/xml; charset=utf-8"));
    headers.insert(AUTHORIZATION, HeaderValue::from_str("Basic dXNlcjpwYXNz")?);
    headers.insert("SOAPAction", HeaderValue::from_static("http://example.com/MyOperation"));
    
    let soap_body = build_soap_request("abc", 123);
    
    let response = client
        .post("https://example.com/service")
        .headers(headers)
        .body(soap_body)
        .send()
        .await?;
    
    handle_response(response).await
}

fn build_soap_request(param1: &str, param2: i32) -> String {
    format!(r#"<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
               xmlns:ex="http://example.com/schema">
    <soap:Body>
        <ex:MyOperation>
            <ex:param1>{}</ex:param1>
            <ex:param2>{}</ex:param2>
        </ex:MyOperation>
    </soap:Body>
</soap:Envelope>"#, param1, param2)
}

Advertisement space

⚠️ Important Tips

πŸ”’ Security

  • Always use HTTPS in production
  • Validate SSL certificates
  • Implement proper authentication
  • Configure appropriate timeouts

πŸ› Debug

  • Enable request/response logging
  • Check XML namespaces
  • Test with tools like SoapUI
  • Monitor performance and timeouts

Advertisement space

πŸš€ Next Steps

Continue learning: