Skip to content

SOAP Tool Generation Example

This example shows how to create an OpenPets plugin from a SOAP/WSDL specification.

Example: Currency Conversion SOAP Service

We'll use a public SOAP service to demonstrate the generation process.

Step 1: Create New Pet

bash
pets new currency-converter
cd pets/currency-converter

Step 2: Add SOAP Configuration

Edit package.json to include SOAP specification:

json
{
  "$schema": "https://pets.raggle.co/config.json",
  "name": "@openpets/currency-converter",
  "version": "1.0.0",
  "title": "Currency Converter",
  "subtitle": "Convert currencies using SOAP service",
  "description": "Currency conversion plugin using legacy SOAP web service",
  "main": "index.ts",
  "types": "index.ts",
  "soapSpec": {
    "url": "http://www.dataaccess.com/webservicesserver/NumberConversion.wso?WSDL",
    "authType": "basic",
    "authEnvVar": "CURRENCY_CONVERTER_API_KEY"
  },
  "envVariables": {
    "optional": [
      {
        "name": "CURRENCY_CONVERTER_API_KEY_USERNAME",
        "description": "SOAP service username (if required)",
        "provider": "Currency Converter",
        "priority": 1
      },
      {
        "name": "CURRENCY_CONVERTER_API_KEY_PASSWORD",
        "description": "SOAP service password (if required)",
        "provider": "Currency Converter",
        "priority": 2
      }
    ]
  },
  "queries": [
    "convert number to words",
    "convert currency"
  ],
  "dependencies": {
    "openpets-sdk": "workspace:*",
    "soap": "^1.0.0",
    "dotenv": "^16.0.0"
  }
}

Step 3: Generate SOAP Tools

bash
# Install dependencies
bun install

# Generate SOAP client and tools
pets generate-soap --verbose

Output:

🔧 Generating SOAP tools from WSDL...
ℹ Fetching WSDL from URL
ℹ WSDL downloaded successfully
ℹ Generating TypeScript client with wsdl-tsclient
ℹ Found 4 SOAP operations
ℹ Generated SOAP client
ℹ Generated SOAP tools
✅ Generated 4 SOAP tools from WSDL
📁 Client: /path/to/pets/currency-converter/soap-client.ts
📁 Tools: /path/to/pets/currency-converter/soap-tools.ts

Step 4: Review Generated Files

soap-client.ts

typescript
/**
 * SOAP Client Utilities
 *
 * Auto-generated from WSDL: http://www.dataaccess.com/webservicesserver/NumberConversion.wso?WSDL
 * Generated: 2025-02-04T10:30:00.000Z
 */

import soap from "soap"
import { createLogger, loadEnv } from "openpets-sdk"

const logger = createLogger("soap-client")
const env = loadEnv(process.cwd())

export const WSDL_URL = "http://www.dataaccess.com/webservicesserver/NumberConversion.wso?WSDL"

export async function createSOAPClient(): Promise<any> {
  try {
    const client = await soap.createClientAsync(WSDL_URL, {
      wsdl_headers: getAuthHeaders()
    })

    client.setSecurity(new soap.BasicAuthSecurity(
      env.CURRENCY_CONVERTER_API_KEY_USERNAME || "",
      env.CURRENCY_CONVERTER_API_KEY_PASSWORD || ""
    ))

    logger.info("SOAP client created successfully")
    return client
  } catch (error: any) {
    logger.error("Failed to create SOAP client", { error: error.message })
    throw error
  }
}

export async function callSOAPOperation(
  operationName: string,
  args: any
): Promise<any> {
  const client = await createSOAPClient()

  try {
    const method = client[`${operationName}Async`]
    if (!method) {
      throw new Error(`Operation ${operationName} not found`)
    }

    const result = await method.call(client, args)
    return result[0]
  } catch (error: any) {
    logger.error("SOAP operation failed", { operationName, error: error.message })
    throw error
  }
}

// ... more utilities

soap-tools.ts

typescript
/**
 * SOAP Tool Definitions
 *
 * Auto-generated SOAP operations as OpenPets tools
 */

import { z, type ToolDefinition } from "openpets-sdk"
import { callSOAPOperation } from "./soap-client"

const soapTools: ToolDefinition[] = [
  {
    name: "soap-number-to-words",
    description: "Convert a number to words",
    schema: z.object({
      params: z.string().optional().describe("JSON string of operation parameters")
    }),
    async execute(args) {
      try {
        const params = args.params ? JSON.parse(args.params) : {}
        const result = await callSOAPOperation("NumberToWords", params)

        return JSON.stringify({
          success: true,
          operation: "NumberToWords",
          result
        }, null, 2)
      } catch (error: any) {
        return JSON.stringify({
          success: false,
          operation: "NumberToWords",
          error: error.message
        }, null, 2)
      }
    }
  },

  // ... more tools
]

export default soapTools

Step 5: Integrate in index.ts

typescript
import { config as loadDotenv } from "dotenv"
import { createPlugin, createLogger, loadEnv, z } from "openpets-sdk"
import soapTools from "./soap-tools"

loadDotenv()

export const CurrencyConverterPlugin = async () => {
  const logger = createLogger("currency-converter")
  const env = loadEnv("currency-converter")

  const customTools = [
    {
      name: "currency-converter-test-connection",
      description: "Test SOAP connection to currency converter service",
      schema: z.object({}),
      async execute() {
        try {
          return JSON.stringify({
            success: true,
            status: "connected",
            message: "SOAP service available"
          }, null, 2)
        } catch (error: any) {
          return JSON.stringify({
            success: false,
            status: "error",
            message: error.message
          }, null, 2)
        }
      }
    }
  ]

  return createPlugin([
    ...customTools,
    ...soapTools
  ])
}

export default CurrencyConverterPlugin

Step 6: Test the Plugin

bash
# Test connection
bun test:pet currency-converter --query "test connection"

# Use SOAP operation
bun test:pet currency-converter --query "convert number 123 to words"

Advanced Configuration

Custom Authentication

For different auth types, update package.json:

json
{
  "soapSpec": {
    "url": "https://api.example.com/service?wsdl",
    "authType": "wssecurity",  // Options: basic, wssecurity, bearer, clientssl, ntlm
    "authEnvVar": "MY_SERVICE_API_KEY"
  }
}

Manual Generation

You can also run generation manually:

bash
# From WSDL URL
pets generate-soap \
  --url http://example.com/service?wsdl \
  --auth-type basic \
  --auth-env-var MY_SERVICE_API \
  --verbose

# From local WSDL file
pets generate-soap \
  --file ./service.wsdl \
  --auth-type wssecurity \
  --output-client my-client.ts \
  --output-tools my-tools.ts

# Preview without writing files
pets generate-soap --url http://example.com/service?wsdl --dry-run

# Generate only TypeScript definitions
pets generate-soap --url http://example.com/service?wsdl --definitions-only

Real-World Example: HM Land Registry

For a production example with SSL certificates and complex authentication:

bash
pets new land-registry
cd pets/land-registry

# Add SOAP configuration
cat > package.json <<EOF
{
  "name": "@openpets/land-registry",
  "version": "1.0.0",
  "soapSpec": {
    "url": "https://bgtest.landregistry.gov.uk/b2b/BGStubService?wsdl",
    "authType": "basic",
    "authEnvVar": "LAND_REGISTRY_API_KEY"
  },
  "envVariables": {
    "required": [
      {
        "name": "LAND_REGISTRY_API_KEY_USERNAME",
        "description": "HM Land Registry username",
        "provider": "HM Land Registry",
        "priority": 1
      },
      {
        "name": "LAND_REGISTRY_API_KEY_PASSWORD",
        "description": "HM Land Registry password",
        "provider": "HM Land Registry",
        "priority": 2
      }
    ]
  },
  "dependencies": {
    "openpets-sdk": "workspace:*",
    "soap": "^1.0.0",
    "dotenv": "^16.0.0"
  }
}
EOF

# Generate SOAP tools
pets generate-soap --verbose

This page is the complete SOAP generation walkthrough.

Troubleshooting

wsdl-tsclient not found

bash
# Install globally
npm install -g wsdl-tsclient

# Or let the generator install it automatically
pets generate-soap --verbose

SOAP dependency missing

bash
# Add soap package
bun add soap

WSDL fetch fails

bash
# Download WSDL manually
curl https://api.example.com/service?wsdl > service.wsdl

# Generate from local file
pets generate-soap --file ./service.wsdl

SSL certificate errors

For services requiring SSL certificates:

typescript
// In soap-client.ts, add SSL options
const client = await soap.createClientAsync(WSDL_URL, {
  wsdl_headers: getAuthHeaders(),
  cert: readFileSync(env.CERT_PATH),
  key: readFileSync(env.KEY_PATH)
})

Resources