savonrb/savon
savonrb/savon has 2,084 GitHub stars and 609 forks. GitHot measured 0 stars in 24 hours. Last checked 2026-11-06 23:53 UTC. Last push 2026-10-31.
Heavy metal SOAP client
Measured star growth
- in 24h
- 0
- in 7 days
- Collecting history
- in 15 days
- Collecting history
- in 1 month
- Collecting history
Net star changes over overlapping periods, not daily totals. Missing measurements are left blank. Stars measure attention, not software quality.
README.md
OriginalSavon
Heavy metal SOAP client
Savon is a SOAP client for Ruby. SOAP is the protocol 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.
Installation
gem 'savon', '~> 2.17'
Usage
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:
client = Savon.client(
wsdl: 'https://service.example.com?wsdl',
pretty_print_xml: true,
log: true
)
Authentication
Most enterprise services require authentication. Common options:
# 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 on the website for HTTP digest, NTLM, and certificate-based options.
Transport
Savon uses 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.
MTOM/XOP attachments
To send a binary file with MTOM, pass a pre-built envelope with an xop:Include reference, set mtom: true, and give the matching attachment. The Content-ID must match the cid: href; set content_id: on the attachment when it differs from the filename:
client.call(:upload,
xml: <<~XML,
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xop="http://www.w3.org/2004/08/xop/include">
<soap:Body>
<tns:upload><tns:file><xop:Include href="cid:doc1@example"/></tns:file></tns:upload>
</soap:Body>
</soap:Envelope>
XML
mtom: true,
attachments: [{ filename: "report.pdf", content_id: "doc1@example", content: File.binread("report.pdf") }]
)
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. The changelog format is Keep a Changelog.
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 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. 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 gem is an alternative.
MTOM/XOP support is request framing only. Savon can emit outbound MTOM/XOP request framing, but it does not rewrite normal base64 XML into XOP, generate xop:Include nodes, validate references, infer MIME types from XML, or deserialize inbound MTOM responses. Callers provide the xop:Include XML and matching attachment Content-IDs. mtom: true without attachments has no effect. For SOAP 1.2, the action is still sent as a SOAPAction header, as elsewhere in Savon, rather than as the action= parameter of the start-info media type.
Contributing
See CONTRIBUTING.md. Everyone interacting in Savon's codebases, issue trackers, and discussion forums is expected to follow the Code of Conduct. MIT licensed.
Explore related projects
codecrafters-io/build-your-own-x
Master programming by recreating your favorite technologies from scratch.
560,441 starspublic-apis/public-apis
A collective list of free APIs
496,760 starsmorluto/rea
Reverse engineer anything with agents, from app behavior down to native binaries.
438,039 starsopenclaw/openclaw
The AI that really does things. Any OS. Any Platform. The lobster way. 🦞
394,071 stars