Documentation
¶
Overview ¶
Package soap provides primitives for SOAP (Simple Object Access Protocol).
Index ¶
- Constants
- func DefaultCheckRetry(err error, request *http.Request, response *http.Response) bool
- type Body
- type Client
- type ClientOption
- func WithCheckRetry(checkRetry func(error, *http.Request, *http.Response) bool) ClientOption
- func WithDebug(debug bool) ClientOption
- func WithEndpoint(endpoint string) ClientOption
- func WithInterceptor(interceptor func(http.RoundTripper) http.RoundTripper) ClientOption
- func WithMaxRetries(retries int) ClientOption
- func WithTimeout(timeout time.Duration) ClientOption
- func WithXMLDeclaration(include bool) ClientOption
- type Detail
- type Envelope
- type EnvelopeOption
- type Error
- type Fault
- type Header
- type HeaderEntry
Examples ¶
Constants ¶
const Namespace = "http://schemas.xmlsoap.org/soap/envelope/"
Namespace is the standard SOAP 1.1 envelope namespace
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Body ¶ added in v0.21.0
type Body struct { XMLName xml.Name // Content as raw XML for maximum flexibility // This allows both simple payloads and complex nested structures Content []byte `xml:",innerxml"` // Additional attributes for extensibility Attrs []xml.Attr `xml:",any,attr"` }
Body represents a SOAP body containing the main message payload. As per SOAP 1.1 spec section 4.3, it contains body entries.
type Client ¶ added in v0.22.0
type Client struct {
// contains filtered or unexported fields
}
Client represents a generic SOAP HTTP client that can handle any type of SOAP request. It works with Envelope types and provides a clean abstraction over HTTP transport.
func NewClient ¶ added in v0.22.0
func NewClient(opts ...ClientOption) (*Client, error)
NewClient creates a new SOAP client with the specified options. Returns an error if the configuration is invalid.
type ClientOption ¶ added in v0.22.0
type ClientOption func(*clientConfig)
ClientOption configures a Client using the functional options pattern. Can be used both during client creation and per-call.
func WithCheckRetry ¶ added in v0.27.0
WithCheckRetry sets a custom retry check function. If not provided, uses DefaultCheckRetry for generic HTTP retry logic.
func WithDebug ¶ added in v0.22.0
func WithDebug(debug bool) ClientOption
WithDebug enables debug mode, which will dump HTTP requests and responses to stderr. This works the same as the debug mode in the soapcall package.
func WithEndpoint ¶ added in v0.22.0
func WithEndpoint(endpoint string) ClientOption
WithEndpoint sets the default SOAP endpoint URL. This can be overridden per call if needed in the future.
func WithInterceptor ¶ added in v0.27.0
func WithInterceptor(interceptor func(http.RoundTripper) http.RoundTripper) ClientOption
WithInterceptor adds a request interceptor for the Client.
func WithMaxRetries ¶ added in v0.27.0
func WithMaxRetries(retries int) ClientOption
WithMaxRetries sets the maximum number of retries for a request. Defaults to 3.
func WithTimeout ¶ added in v0.27.0
func WithTimeout(timeout time.Duration) ClientOption
WithTimeout sets the timeout for the SOAP client.
func WithXMLDeclaration ¶ added in v0.22.0
func WithXMLDeclaration(include bool) ClientOption
WithXMLDeclaration controls whether XML declaration is automatically added to requests. Defaults to true. Set to false if your SOAP service doesn't expect or allow XML declarations.
type Detail ¶ added in v0.21.0
type Detail struct { // Content as raw XML to accommodate any application-specific fault data Content []byte `xml:",innerxml"` // Additional attributes for extensibility Attrs []xml.Attr `xml:",any,attr"` }
Detail represents application-specific fault detail information.
type Envelope ¶ added in v0.21.0
type Envelope struct { XMLName xml.Name // Optional encoding style as per SOAP 1.1 spec section 4.1.1 EncodingStyle string `xml:"encodingStyle,attr,omitempty"` // Optional header as per SOAP 1.1 spec section 4.2 Header *Header `xml:"Header,omitempty"` // Mandatory body as per SOAP 1.1 spec section 4.3 Body Body `xml:"Body"` // Additional attributes for extensibility as per SOAP 1.1 spec section 4.1 Attrs []xml.Attr `xml:",any,attr"` }
Envelope represents a SOAP envelope with flexible namespace support. It can handle any namespace prefix and URI, making it compatible with various SOAP implementations. The XMLName field determines the actual element name and namespace used in marshaling/unmarshaling.
Example (Basic) ¶
ExampleEnvelope_basic demonstrates creating a basic SOAP envelope with just a body.
// Create a simple SOAP envelope using the new API envelope, err := soap.NewEnvelope(soap.WithBody([]byte(`<GetWeather><city>London</city></GetWeather>`))) if err != nil { log.Fatal(err) } xmlData, err := xml.MarshalIndent(envelope, "", " ") if err != nil { log.Fatal(err) } fmt.Println(string(xmlData))
Output: <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Body><GetWeather><city>London</city></GetWeather></soapenv:Body> </soapenv:Envelope>
Example (Extensibility) ¶
ExampleEnvelope_extensibility demonstrates using custom attributes for extensibility.
envelope, err := soap.NewEnvelope(soap.WithBody([]byte(`<ProcessOrder><orderId>12345</orderId></ProcessOrder>`))) if err != nil { log.Fatal(err) } // Add custom attributes to the body for extensibility envelope.Body.Attrs = []xml.Attr{ {Name: xml.Name{Local: "priority"}, Value: "high"}, } // Add custom attributes to the envelope for extensibility envelope.Attrs = append(envelope.Attrs, []xml.Attr{ {Name: xml.Name{Local: "version"}, Value: "1.2"}, {Name: xml.Name{Local: "trace", Space: "http://example.com/trace"}, Value: "enabled"}, }...) xmlData, err := xml.MarshalIndent(envelope, "", " ") if err != nil { log.Fatal(err) } fmt.Println(string(xmlData))
Output: <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" version="1.2" xmlns:trace="http://example.com/trace" trace:trace="enabled"> <soapenv:Body priority="high"><ProcessOrder><orderId>12345</orderId></ProcessOrder></soapenv:Body> </soapenv:Envelope>
Example (RealWorld) ¶
ExampleEnvelope_realWorld demonstrates creating a SOAP envelope for real-world use.
// Create a SOAP envelope for a weather service request using the new API envelope, err := soap.NewEnvelope(soap.WithBody([]byte(`<GetTemperature xmlns="http://weather.example.com/"><city>Paris</city></GetTemperature>`))) if err != nil { log.Fatal(err) } // Marshal to XML (this is what gets sent to SOAP services) xmlData, err := xml.MarshalIndent(envelope, "", " ") if err != nil { log.Fatal(err) } fmt.Println(string(xmlData))
Output: <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Body><GetTemperature xmlns="http://weather.example.com/"><city>Paris</city></GetTemperature></soapenv:Body> </soapenv:Envelope>
Example (WithEncodingStyle) ¶
ExampleEnvelope_withEncodingStyle demonstrates setting encoding style.
envelope, err := soap.NewEnvelope(soap.WithBody([]byte(`<GetStockPrice><symbol>AAPL</symbol></GetStockPrice>`))) if err != nil { log.Fatal(err) } // Set encoding style for advanced use cases envelope.EncodingStyle = "http://schemas.xmlsoap.org/soap/encoding/" xmlData, err := xml.MarshalIndent(envelope, "", " ") if err != nil { log.Fatal(err) } fmt.Println(string(xmlData))
Output: <soapenv:Envelope encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Body><GetStockPrice><symbol>AAPL</symbol></GetStockPrice></soapenv:Body> </soapenv:Envelope>
Example (WithHeader) ¶
ExampleEnvelope_withHeader demonstrates creating a SOAP envelope with headers.
// Create header entries mustUnderstand := true authHeader := soap.HeaderEntry{ XMLName: xml.Name{Local: "Authentication", Space: "http://example.com/auth"}, MustUnderstand: &mustUnderstand, Actor: "http://example.com/gateway", Content: []byte(`<token>abc123xyz</token><user>john.doe</user>`), } transactionHeader := soap.HeaderEntry{ XMLName: xml.Name{Local: "Transaction", Space: "http://example.com/tx"}, Content: []byte(`<id>tx-456</id>`), } // Create envelope with headers using the new API envelope, err := soap.NewEnvelope(soap.WithBody([]byte(`<GetUserProfile><userId>12345</userId></GetUserProfile>`))) if err != nil { log.Fatal(err) } // Add headers manually for advanced use cases envelope.Header = &soap.Header{ XMLName: xml.Name{Local: "soapenv:Header"}, Entries: []soap.HeaderEntry{authHeader, transactionHeader}, } xmlData, err := xml.MarshalIndent(envelope, "", " ") if err != nil { log.Fatal(err) } fmt.Println(string(xmlData))
Output: <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header> <Authentication xmlns="http://example.com/auth" mustUnderstand="true" actor="http://example.com/gateway"><token>abc123xyz</token><user>john.doe</user></Authentication> <Transaction xmlns="http://example.com/tx"><id>tx-456</id></Transaction> </soapenv:Header> <soapenv:Body><GetUserProfile><userId>12345</userId></GetUserProfile></soapenv:Body> </soapenv:Envelope>
func NewEnvelope ¶ added in v0.22.0
func NewEnvelope(opts ...EnvelopeOption) (*Envelope, error)
NewEnvelope creates a new SOAP envelope with the specified options.
type EnvelopeOption ¶ added in v0.22.0
type EnvelopeOption func(*envelopeConfig)
EnvelopeOption is a function that configures an Envelope.
func WithBody ¶ added in v0.22.0
func WithBody(body any) EnvelopeOption
WithBody sets the body for the Envelope.
func WithNamespace ¶ added in v0.22.0
func WithNamespace(prefix, namespace string) EnvelopeOption
WithNamespace sets the namespace for the Envelope.
type Error ¶ added in v0.27.0
type Error struct { // StatusCode is the HTTP status code of the response. StatusCode int // ResponseBody is the raw HTTP response body. ResponseBody []byte // Envelope is the SOAP envelope that was received, nil if parsing failed. Envelope *Envelope // Fault is the SOAP fault, nil if no fault was present. Fault *Fault }
Error contains HTTP and SOAP fault information.
type Fault ¶ added in v0.21.0
type Fault struct { XMLName xml.Name // FaultCode is mandatory and provides algorithmic fault identification FaultCode string `xml:"faultcode"` // FaultString is mandatory and provides human-readable fault description FaultString string `xml:"faultstring"` // FaultActor is optional and identifies the fault source FaultActor string `xml:"faultactor,omitempty"` // Detail is optional and contains application-specific error information Detail *Detail `xml:"detail,omitempty"` }
Fault represents a SOAP fault element as per SOAP 1.1 spec section 4.4.
Example ¶
ExampleFault demonstrates creating and handling SOAP faults.
// Create a fault fault := soap.Fault{ FaultCode: "Client", FaultString: "Invalid authentication credentials", FaultActor: "http://example.com/auth-service", Detail: &soap.Detail{ Content: []byte(`<error><code>AUTH001</code><message>Token expired</message></error>`), }, } faultXMLData, _ := xml.Marshal(fault) envelope, err := soap.NewEnvelope(soap.WithBody(faultXMLData)) if err != nil { log.Fatal(err) } xmlData, err := xml.MarshalIndent(envelope, "", " ") if err != nil { log.Fatal(err) } fmt.Println(string(xmlData))
Output: <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Body><Fault><faultcode>Client</faultcode><faultstring>Invalid authentication credentials</faultstring><faultactor>http://example.com/auth-service</faultactor><detail><error><code>AUTH001</code><message>Token expired</message></error></detail></Fault></soapenv:Body> </soapenv:Envelope>
type Header ¶ added in v0.21.0
type Header struct { XMLName xml.Name // Header entries - flexible content allowing any XML Entries []HeaderEntry `xml:",any"` // Additional attributes for extensibility Attrs []xml.Attr `xml:",any,attr"` }
Header represents a SOAP header containing header entries. Each header entry can have mustUnderstand and actor attributes as per SOAP 1.1 spec section 4.2.
type HeaderEntry ¶ added in v0.21.0
type HeaderEntry struct { XMLName xml.Name // MustUnderstand attribute as per SOAP 1.1 spec section 4.2.3 // Values: true (1) means mandatory, false (0) or nil means optional MustUnderstand *bool `xml:"mustUnderstand,attr,omitempty"` // Actor attribute as per SOAP 1.1 spec section 4.2.2 // Specifies the intended recipient of this header entry Actor string `xml:"actor,attr,omitempty"` // Content as raw XML for maximum flexibility Content []byte `xml:",innerxml"` // Additional attributes for extensibility Attrs []xml.Attr `xml:",any,attr"` }
HeaderEntry represents a single header entry with SOAP-specific attributes. Implements the mustUnderstand and actor semantics from SOAP 1.1 spec sections 4.2.2 and 4.2.3.
Example (MustUnderstand) ¶
ExampleHeaderEntry_mustUnderstand demonstrates the mustUnderstand attribute usage.
// Header that MUST be understood by the receiver mustUnderstand := true criticalHeader := soap.HeaderEntry{ XMLName: xml.Name{Local: "Security", Space: "http://example.com/security"}, MustUnderstand: &mustUnderstand, Content: []byte(`<signature>digital_signature_here</signature>`), } // Header that's optional optionalHeader := soap.HeaderEntry{ XMLName: xml.Name{Local: "Metadata", Space: "http://example.com/meta"}, Content: []byte(`<version>2.0</version>`), // MustUnderstand is nil, so it's optional } envelope, err := soap.NewEnvelope(soap.WithBody([]byte(`<SecureOperation><data>sensitive</data></SecureOperation>`))) if err != nil { log.Fatal(err) } // Add headers manually for advanced use cases envelope.Header = &soap.Header{ XMLName: xml.Name{Local: "soapenv:Header"}, Entries: []soap.HeaderEntry{criticalHeader, optionalHeader}, } xmlData, err := xml.MarshalIndent(envelope, "", " ") if err != nil { log.Fatal(err) } fmt.Println(string(xmlData))
Output: <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header> <Security xmlns="http://example.com/security" mustUnderstand="true"><signature>digital_signature_here</signature></Security> <Metadata xmlns="http://example.com/meta"><version>2.0</version></Metadata> </soapenv:Header> <soapenv:Body><SecureOperation><data>sensitive</data></SecureOperation></soapenv:Body> </soapenv:Envelope>