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:
- Use the WSDL Viewer to analyze your services
- Explore advanced tools for development
- Practice with public SOAP services for testing