Accessing a Web Service

I’ve been wrangling round and round with the contents of the http.request table, trying to post to a web service. Somewhere, I’m just conceptually off track.

Does anyone have an example of accessing a web-service from Codea? Thanks.

Here: http://codea.io/talk/discussion/4220/php-lua-help-sending-email#Item_14
It’s pretty easy to understand after you get started, in my opinion.

The service I’m using is a SOAP / XML based web service, and setting up the headers, the SOAP envelope, and the content turns out to be a bit trickier than might be expected. However, after batting it around a bit, I’ve worked out enough to get my app talking to the service.

In my case, the WSDL for the service looks something like this:

POST /tracking/tracking.asmx HTTP/1.1
Host: myserver
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://MyCompany.com/SubmitTracking"

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <SubmitTracking xmlns="http://PeabodyEnergy.com/">
      <packageXML>string</packageXML>
    </SubmitTracking>
  </soap:Body>
</soap:Envelope>

To access the SOAP Service, you need to set up a header table with these values.

headers = {["Host"] = "myserver", ["Content-Type"] ="text/xml; charset=utf-8", ["Content-Length"] = (length my contents + the SOAP envelope), ["SOAPACTION"]="http://MyCompany.com/SubmitTracking"}

The actual contents of a the data the web service takes is XML, which goes into the “string” spot in the XML above. For reasons unknown to me, this tends to throw a “null value” error if I use normal “<” and “>” carets, but it works fine with the explicit “<” and “>” so the information I send looks like this.

   <PACKET>
     <LOCATION X = "100" Y = "100" Z="100" />
     <LOCATION X = "100" Y = "100" Z="100" />
   </PACKET>

I set up a string “contents” that has this xml.

I also need to set up the envelope, so I I set up a string holding the top half of the envelope as described in the WSDL down to “packageXML” and another that has the bottom portion.

Then I bundle it all into a string

data = envTop + contents + envBottom

And finally, it’s time to dispatch it all to the url. So I set up my table…

        tbl = {["method"] = "POST", ["data"] = data, ["headers"] = headers}
        http.request(url, gotData, gotError, tbl)

And… tah dah! It actually works.

One other handy tip: while the SOAPAction looks like a URL, it’s not. And it’s case sensitive.

By the way, I’m not expecting anyone to debug the mess above. I’m just looking for an exampe of something similar that works.

After pounding on it some more, I’m getting close. I’m past the land of Error 400 and into the land of errors actually returned by the web service in complaints about values. When I work out where I’ve gone wrong, I’ll post the solution, but I’d still love to see a well done example.

Thanks.

@jmv38 Maybe. It seems strange that the < and > work fine in the SOAP Envelope / SOAP Body, but once you’re into the package contents they cause an issue. However, I’m just happy to have a work around.

OK, I’m now successfully sending and retrieving data from a SOAP service. The code above has been corrected to be valid as an example.

One issue that’s come up on more complex services – such as those that use PackageXML or another wrapper for a number of internal parameters not visible in the WSDL – for reasons unknown to me, using the actual “<” and “>” characters doesn’t seem valid. However, changing those characters to “& lt;” and “& gt;” stops the problem.

@Mark this is maybe due to the special meaning of > and < in html?

@Mark, you say changing “<” and “>” to “<” and “>” stops the problem? What is the difference?

It’s the %$!# forum code trying to be helpful.

Changing “<” and “>” to “& lt;” and “& gt;” makes the difference, only imagine it without the space in the middle.

@Mark, I see. The forum interprets the HTML and changes it for you. using the code tags like so: < would work.