# Savon Heavy metal SOAP client [![CI](https://github.com/savonrb/savon/actions/workflows/ci.yml/badge.svg)](https://github.com/savonrb/savon/actions/workflows/ci.yml) [![Gem Version](https://img.shields.io/gem/v/savon.svg)](https://rubygems.org/gems/savon) [![Coverage Status](https://coveralls.io/repos/github/savonrb/savon/badge.svg?branch=main)](https://coveralls.io/github/savonrb/savon?branch=main) Savon is a SOAP client for Ruby. [SOAP is the protocol](https://www.w3.org/TR/soap/) spoken by many enterprise systems. When they hand you a WSDL URL or file instead of a REST spec, it's SOAP. Savon reads the WSDL, maps available operations to Ruby symbols, converts Ruby hashes to SOAP envelopes and turns XML responses into hashes you can work with. Full documentation is at [savonrb.com](https://savonrb.com). ## Installation ```ruby gem 'savon', '~> 2.17' ``` ## Usage ```ruby require 'savon' # Point Savon to a local or remote WSDL document client = Savon.client(wsdl: 'https://service.example.com?wsdl') # See what the service exposes client.operations # => [:find_user, :create_user] # Make a request and work with the response response = client.call(:find_user, message: { id: 42 }) response.body[:find_user_response] # => { id: 42, name: "Hoff" } # Savon raises a Savon::SOAPFault when the server returns a SOAP fault rescue Savon::SOAPFault => e puts e.to_hash.dig(:fault, :faultstring) ``` Enable logging to see the raw SOAP envelopes. That's probably the single most useful thing while getting a new integration working: ```ruby client = Savon.client( wsdl: 'https://service.example.com?wsdl', pretty_print_xml: true, log: true ) ``` ### Authentication Most enterprise services require authentication. Common options: ```ruby # HTTP basic auth Savon.client(wsdl: '...', basic_auth: ['user', 'secret']) # WS-Security (WSSE) Savon.client(wsdl: '...', wsse_auth: ['user', 'secret', :digest], wsse_timestamp: true) ``` See [Authentication](https://savonrb.com/version2/globals.html) on the website for HTTP digest, NTLM, and certificate-based options. ### Transport Savon uses [HTTPI](https://github.com/savonrb/httpi) for HTTP by default. Since v2.17.0 you can opt-in to use Faraday by passing `transport: :faraday` which exposes the Faraday connection at `client.faraday` for you to configure. Savon is only adding some SOAP-specifics on top. ## Ruby support Savon 2.x requires Ruby >= 3.0.0, kept as the lower bound for backward compatibility. Note that Ruby 3.0–3.3 are EOL or security-only. Ruby 3.4+ is the minimum version with active maintenance. ## Versioning & stability Savon follows [Semantic Versioning 2.0.0](https://semver.org/spec/v2.0.0.html). The changelog format is [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). **The 2.x line is anchored on 2.12.1.** Every 2.x release is supposed to be safe to upgrade to from 2.12.1, and anything that worked in 2.12.1 keeps working. We do not remove or rename public APIs in the 2.x line. New behavior is opt-in and requires an explicit option change. If you found a problem with that, please let us know. We only soft-deprecate APIs we plan to remove. The `Deprecated` sections of the [changelog](CHANGELOG.md) list every API that is planned to be removed with version 3.0. Callers on 2.13.0–2.15.x may see specific post-2.12.1 behaviors restored to the 2.12.1 contract. This is intentional. ## Known limitations **WSDL imports are not followed.** Savon parses only the root WSDL document via [Wasabi](https://github.com/savonrb/wasabi). Messages, port types, and bindings defined in imported files are invisible to Savon. If you control the WSDL, merge the imported elements into the root document and pass that to Savon as a string. If you need full import support, the [WSDL](https://rubygems.org/gems/wsdl) gem is an alternative. ## Contributing See [CONTRIBUTING.md](CONTRIBUTING.md). MIT licensed.