Thursday, July 16, 2009

Erlang and SOAP Webservice

I just completed invoking SOAP Webservice from Erlang.

Here is what I did,

  1. inets:start(), This is very important without which http:request will not be succeeded.
  2. Took a shortcut: (hm.. not actually) I treated SOAP Call as Http POST call.
  3. I used Erlang http module
    1. http:request( post, URL, [{"Host" , Host}, {"SOAPAction", ""}],

"text/xml", getData ()},

[ {timeout, 5000} ], [{body_format, binary}])

    1. Used case expression to handle different condition
  1. getData() returns binary form of soap message. Here, correct payload of SOAP Request will be needed to make this request template. It returns binary form of the SOAP payload (String form can also be used)
  2. http:request would return either
    1. {ok, Result} -> Handle successful http request
    2. {error, Reason} -> Handle Errors
    3. {ok, saved_to_file}-> if you use “stream” option, this pattern will be invoked and it is optional.
  3. Result is response payload (http payload) and can be processed

Note:

Erlang has good support for Proxy and Proxy authentication unlike python. Python is mess in this area.

5 comments:

  1. please, can you post a full example? maybe using a public web service?

    thanks in advance
    http://www.redaelli.org/matteo/

    ReplyDelete
  2. Thanks for contacting me.... I used plain http to make POST request.
    Here is the code to lat lang service,
    call
    soap:lang_lat_service("ZIP_CODE").


    Sorry for the bad indentation.

    -module(soap).
    -export([lang_lat_service/1]).
    -define(URL,"http://www.weather.gov/forecasts/xml/SOAP_server/ndfdXMLserver.php"\
    ).
    -define(HOST,"http://www.weather.gov").


    lang_lat_service(ZipCode) ->
    io:format("Data is ~p~n", [ZipCode]),
    RequestPayload = getData(ZipCode),
    io:format("Data is ~p~n", [RequestPayload]),
    make_call(RequestPayload),
    ok.

    make_call(Data)->
    inets:start(),
    {ok, Result} = http:request( post, {?URL, [{"Host" , ?HOST}, {"SOAPAction", \
    "http://www.weather.gov/forecasts/xml/DWMLgen/wsdl/ndfdXML.wsdl#LatLonListZipCod\
    e"}], "text/xml", Data}, [ {timeout, 5000} ], [{body_format, binary}]), io:fo\
    rmat("Soap Response is ~p~n", [Result]),
    Result.


    process_request(Result)->
    %% case {ok, Result} ->
    %% io:format("Soap Response is ~p~n", [Result]);
    %% {error, Reason} ->
    %% io:format("Error is ~p~n", [Reason])
    %% end.
    ok.

    getData(ZipCode)->
    XmlData = " <soapenv:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-i\
    nstance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soapenv=\"http://\
    schemas.xmlsoap.org/soap/envelope/\" xmlns:ndf=\"http://www.weather.gov/forecast\
    s/xml/DWMLgen/wsdl/ndfdXML.wsdl\"> <soapenv:Header/> <soapenv:Body> <nd\
    f:LatLonListZipCode soapenv:encodingStyle=\"http://schemas.xmlsoap.org/soap/enco\
    ding/\"> <zipCodeList xsi:type=\"dwml:zipCodeListType\" xmlns:dwml=\"htt\
    p://www.weather.gov/forecasts/xml/DWMLgen/schema/DWML.xsd\">"
    ++ ZipCode
    ++ "</zipCodeList> </ndf:LatLonListZipCode> </soapenv:Body></soap\
    env:Envelope>"


    ReplyDelete
  3. Hi Sethilkumar,

    Thanks for the codes. It helps me a lot.

    :)

    Abe

    ReplyDelete
  4. Abe, better way to handle web service is to use XML parsing capabilities available in Erlang but I wanted to show how to use raw http api to invoke web service as it is "glorified" http designed by committee ;-)

    ReplyDelete

Thanks for reading and welcome for commenting...