How to create a soap service in elixir and phoenix. I went through some of the links but nowhere I could get complete guidance on development of a soap service in elixir and phoenix. I have a wsdl url and a request xml. On hitting the wsdl url with the request xml in soap ui, I am getting a proper response. I want to develop this calling of the wsdl and getting a response in elixir and phoenix. What should I refer to. Could not find very useful reference till now. Can someone please guide me.
If you can, build a REST-to-SOAP service in a language that has good SOAP support. I have tried all of the various SOAP libraries in Erlang and Elixir and have yet to find one that can properly parse the WSDLs that I had to deal with (they all failed at some point or another)
I ended up using Ruby with soap4r
(well, soap4r-ng
), because neither savon
nor lolsoap
could handle the complexity of the SOAP service I used.
SOAP is a nasty piece of work because itās fully object oriented and if your service was built system-first, rather than WSDL-first, you will have heavy object orientation and polymorphism to deal with and pretty much all of the Erlang/Elixir SOAP services that I played with failed.
If I have to deal with another SOAP service (Iām usually doing enterprise integrations, so itās not unlikely), I will either do the same thing or build my own WSDL/WSSE/SOAP layer with the goal of open sourcing it, but thatās probably a year in the future at least. Itās a hard thing, because once we got started with the soap4r
approach, we had our gateway and Elixir code implemented in about two weeks. It would have taken two weeks just to get a working WSDL parser for Elixir to handle the multiple WSDLs I had to deal with.
I love Elixir, but thereās no good answer to doing SOAP in Elixir at this point.
Thanks Austin for sharing your experience. My requirement is SOAP service only in Elixir. I have only 1 WSDL which I have to work on.
I referrred to the below link for implementation but the tutorial is not so good:-
I understand. You might have success with one of the various projects I list below, but it entirely depends on whether the WSDL represents something that was written and the service code was written from itā¦or whether the WSDL is something generated from the service code. The former presents interfaces that conform to spec far more frequently and simply. The latter will do things that are possible in the spec, but donāt happen in WSDL-first services, which means that most WSDL parsers handle them poorly.
Here are all the toolkits Iāve tried before basically punting:
- elixir-soap/soap
- trbngr/Lyex
- polyfox/castile
- bet365/soap
- zdeneksejcek/soapex
Of these, bet365/soap is the most mature but hasnāt been maintained in years; polyfox/castile is promising but hasnāt been maintained in a long time; zdeneksejcek/soapex is really interesting but incomplete. None of them worked with any one of the four WSDLs I had to work with.
If yours is a simple enough service, youād probably be better off building EEx templates for sending the requests and XML parsers for receiving the requests and calling the services with an HTTP client (most SOAP is over HTTPS, after all).
If itās not a simple serviceā¦all I can say is good luck doing it in Elixir. SOAP is a technology that only works really well if you have relatively large engineering teams building the code tooling around the excessively complicated standards. The absolute best platforms/languages to develop SOAP services and clients are Java and C#ābecause the SOAP standards were mostly written by people who work at Oracle (and Sun before that), IBM, SAP, and Microsoft.
The truth is, I donāt want to write a SOAP client in Elixirābecause I donāt want to use SOAP if I can avoid it, and that disdain also means that Iām not likely to maintain it (even the Ruby toolkit that I ended up using, soap4r-ng
, hasnāt been maintained in a few years, but itās a lot more mature than anything in Elixir/Erlang that does SOAP).
Good summary. Iād question OPās requirement to create SOAP service (of all things!) but they might be stuck with a strong-headed customer.
@rameshsharma Are there not other options? What are you trying to achieve exactly?
Thanks Austin for the detailed summary.
I have a wsdl url mentioned below. I have to develop a soap service to hit the wsdl using a request xml and get a response. Based on the below url can you suggest me the best approach of work.
https://sandbox.ws-idu.tracesmart.co.uk/v5.6/?wsdl
Is there any reference link of the above point mentioned by you:
āāIf yours is a simple enough service, youād probably be better off building EEx templates for sending the requests and XML parsers for receiving the requests and calling the services with an HTTP client (most SOAP is over HTTPS, after all).āā
This is based on a quick reading of the WSDL, but I think that itās simple enough (it isnāt using any polymorphism that I can see, except in arrays) that it should work with pretty much any of the existing toolkits. It is not simple enough that you could reliably make EEx templates without a lot of example payloads.
The EEx template approach is just one where you get a full-change payload and then use EEx template logic, looping, and substitution to build an appropriate XML file for a payload.
Thanks Austin. So I think then I can go for elixir-soap/soap.
I am completely new to SOAP service in Elixir. The documentation below does not clearly state how to send request xml to hit the wsdl and get the response back.
Is there any reference anywhere?
On hitting the below command in interactive shell, I am getting the below output.
iex:4> {:ok, wsdl} = Soap.init_model(āhttps://sandbox.ws-idu.tracesmart.co.uk/v5.6/?wsdlā, :url)
{:ok,
%{
complex_types: [],
endpoint: āā,
messages: [],
namespaces: %{},
operations: [],
schema_attributes: %{element_form_default: āā, target_namespace: āurn:iduā},
soap_version: ā1.1ā,
validation_types: %{}
}}
Not sure why complex_types, operations are all showing [].
Donāt neglect erlang libraries for soap handling as well. Soap was more of a big thing back in erlangās creation days.
But for note, soap is just (mostly) xml in various defined ways, itās not hard to do it manually with no libraries at all.
Thanks, by erlang library you mean to refer to bet365/soap ??
I donāt think that existed when I last did soap in erlang, I donāt recall what I used, it was over 10 years ago (maybe 15 years? yeeshā¦). ^.^;
I looked at the Erlang libraries, too. Most of them are incomplete, but more complete than the Elixir ones.
Austin, can you please suggest me, which library/toolkit can help me in implementing the soap service completely as per the wsdl which I shared?
Will it be possible to implement or shall I not look into this option of implementing Soap service in Elixir at all. Sorry for asking this again, as I am completely new to Soap in Elixir.
Thanks for all your support.
In the repoās Readme there is this example of a
call and its response:
wsdl_path = "http://www.dneonline.com/calculator.asmx?WSDL"
action = "Add"
params = %{intA: 1, intB: 2}
iex(3)> {:ok, response} = Soap.call(wsdl, action, params)
{:ok,
%Soap.Response{
...
Is it this you were looking for to send requests and get response? Hth
I saw that patrick, but then what should be action and params for my wsdl
https://sandbox.ws-idu.tracesmart.co.uk/v5.6/?wsdl
wsdl_path = āhttps://sandbox.ws-idu.tracesmart.co.uk/v5.6/?wsdlā
action = ??
params = ??
The doc states that you get the available operations (actions) with
Soap.operations(wsdl)
ā¦but now I see that it returns [ ]
And the same value was in the wsdl map returned by {:ok, wsdl} = Soap.init_model(ā¦)
ā¦ rubyās savon gem, instead, finds a single operation: idu_process
Correct patrick, I am getting [] for available operations
iex:5> Soap.operations(wsdl)
[]
I am able to get this with some tweaks in the wsdl namespace and configs
iex:10> Soap.operations(wsdl)
[
%{
input: %{body: nil, header: nil},
name: āIDUProcessā,
soap_action: āurn:idu#Idu#IDUProcessā
}
]
Anyone ever encountered this type of error ā<faultstring xsi:type=āxsd:stringā>method āhttp://schemas.xmlsoap.org/soap/envelope/IDUProcessā not defined in serviceā??
iex:13> Soap.call(wsdl, action, params)
{:ok,
%Soap.Response{
body: ā<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<SOAP-ENV:Envelope\r\n xmlns:SOAP-ENV=āhttp://schemas.xmlsoap.org/soap/envelope/ā\r\n xmlns:xsd=āhttp://www.w3.org/2001/XMLSchemaā\r\n xmlns:xsi=āhttp://www.w3.org/2001/XMLSchema-instanceā\r\n xmlns:SOAP-ENC=āhttp://schemas.xmlsoap.org/soap/encoding/ā\r\n SOAP-ENV:encodingStyle=āhttp://schemas.xmlsoap.org/soap/encoding/ā>\r\nSOAP-ENV:Body\r\nSOAP-ENV:Fault\r\n<faultcode xsi:type=āxsd:QNameā>SOAP-ENV:Server\r\n**<faultstring xsi:type=āxsd:stringā>method āhttp://schemas.xmlsoap.org/soap/envelope/IDUProcessā not defined in service**\r\n<faultactor xsi:type=āxsd:anyURIā>\r\n<detail xsi:type=āxsd:stringā></SOAP-ENV:Fault>\r\n</SOAP-ENV:Body>\r\n</SOAP-ENV:Envelope>\r\nā,