We'll have a review session next week on Tuesday from 11:30am to 1pm,
in Sequoyah Hall room 147. (Sequoyah Hall is north of APM and south
of RIMAC, near the Economics building.)
Today we'll look at SOAP, a simple but useful standard for building
web services. SOAP was defined in 1999. There are many implementations
of it available, but very few public services using it--we'll discuss possible
reasons later.
HTTP traffic is permitted by most firewalls. Note the paradox: because firewalls view other protocols as security risks, we are punching security holes into HTTP.
Currently HTTP is used only for transmitting files. As procedure parameters, we need to transmit structured data such as arrays.
SOAP uses HTTP to define headers for remote procedure calls (commands), and XML to define payloads.
SOAP does not provide encryption, authentication, type safety, versioning,
co-routines, message grouping, call-by-reference, or complex operations
on objects. Because it does not assume object-orientedness, SOAP
is easy to use for small and simple servers, like sensor devices, and server
languages, like PHP.
$send_int=2001; $send_string="happy!"; $send_arr=array("2001","happy" );Here /soap/servlet/rpcrouter is the servlet program on the server office.gigaideas.com.cn at port 8080.
$soap_msg=new soapmsg( 'get_array', //Invoked Method Name
'urn:soap_test', //Invoked Target Object Id
array( //Parameters List Below
new soapval($send_int, "int"),
new soapval($send_string, "string"),
new soapval($send_arr, "array")));
$client=new soap_client("/soap/servlet/rpcrouter", "office.gigaideas.com.cn", 8080);
$return=$client->send($soap_msg);Notice the SOAP client blocks until the response is received. A non-blocking client would be a useful extension to this SOAP implementation.
if (!$return) { die("send failed"); }
$v=$return->value();//Check the response.
if(!$return->faultCode()) {
$back_arr=$v->scalarval();
print "Back array is:\n<br>";
for($i=0;$i<sizeof($back_arr);$i++) echo $i." => ".$back_arr[$i]."\n<br>";
} else {
print "Fault: ";
print "Code: " . $return->faultCode() . " Reason '" .$return->faultString()."'<BR>";
}
And here is the corresponding response:POST /StockQuote HTTP/1.1
Host: www.stockquoteserver.com
Content-Type: text/xml
Content-Length: nnnn
SOAPMethodName: Some-Namespace-URI#GetLastTradePrice<SOAP:Envelope xmlns:SOAP="urn:schemas-xmlsoap-org:soap.v1">
<SOAP:Body>
<m:GetLastTradePrice xmlns:m="Some-Namespace-URI">
<symbol>DIS</symbol>
</m:GetLastTradePrice>
</SOAP:Body>
</SOAP:Envelope>
HTTP/1.1 200 OK
Content-Type: text/xml
Content-Length: nnnn<SOAP:Envelope xmlns:SOAP="urn:schemas-xmlsoap-org:soap.v1">
<SOAP:Body>
<m:GetLastTradePriceResponse xmlns:m="Some-Namespace-URI">
<return>34.5</return>
</m:GetLastTradePriceResponse>
</SOAP:Body>
</SOAP:Envelope>
SOAP allows methods to be invoked against endpoints over HTTP. A SOAP endpoint is identified by a URL (just like any HTTP-based resource). A SOAP method is uniquely identified by a namespace URI and an NCName. The NCName maps to the symbolic name of the method. The namespace URI scopes the method name. SOAP method requests are transported in HTTP POST requests. They must have a SOAPMethodName HTTP header indicating the method being invoked. The following is a minimal SOAP HTTP header:POST /objectURI HTTP/1.1 Host: www.foo.com SOAPMethodName: urn:develop-com:IBank#getBalance Content-Type: text/xml Content-Length: nnnnThis HTTP header indicates that the getBalance method (from the urn:develop-com:IBank namespace) should be invoked against the endpoint identified by http://www.foo.com/objectURI.The HTTP payload of a SOAP method request is an XML document that contains the information needed to invoke the request. Assuming that all that is needed to get a bank balance is an account number, the HTTP payload of the request would look something like this:
<?xml version='1.0'?> <SOAP:Envelope xmlns:SOAP='urn:schemas-xmlsoap-org:soap.v1'> <SOAP:Body> <i:getBalance xmlns:i='urn:develop-com:IBank'> <account>23619-22A</account> </i:getBalance> </SOAP:Body> </SOAP:Envelope>After drilling through the SOAP:Envelope and SOAP:Body elements, note that "root" element of SOAP:Body is an element whose namespace-qualified tag name matches the SOAPMethodName HTTP header exactly. This redundancy is to allow the HTTP-based infrastructure (proxies, firewalls, web server software) to process the call without parsing XML, while also allowing the XML payload to stand independent of the surrounding HTTP message. Since all that was needed to invoke the getBalance method was an account number, only one child element appears below the i:getBalance element.Upon receiving this request, the server-side software is expected to execute some code that corresponds to getBalance. How this happens is completely outside the scope of the SOAP protocol. Here are some possible reactions to the request:
Once the server-side operation has executed, an HTTP response message will be returned to the client containing the results of the operation. There are no SOAP-specific HTTP response headers. However, the HTTP payload will contain an XML document that contains the results of the operation. The results will be inside an element whose name matches the method name suffixed by "Response." Here's an example response message (including the HTTP header):A CGI program may run. An Apache module may be called. An ASP or JSP page may be processed. A Java Servlet or ISAPI extension may be invoked. A servant may be dispatched inside a CORBA ORB. An XSLT may be run against the request. A human may read the request and start typing a response (unlikely, but legal SOAP!). 200 OK Content-Type: text/xml Content-Length: nnnn <?xml version='1.0'?> <SOAP:Envelope xmlns:SOAP='urn:schemas-xmlsoap-org:soap.v1'> <SOAP:Body> <i:getBalanceResponse xmlns:i='urn:develop-com:IBank'> <amount>45.21</amount> </i:getBalanceResponse> </SOAP:Body> </SOAP:Envelope>That's it. SOAP endpoints are just URLs. SOAP methods are just a pair of XML element declarations identified by a namespace URI and an NCName. Section 8 of the SOAP specification describes the rules used to encode instances of types. The section 8 rules describe an element-normal-form encoding style, in which all properties of an instance are encoded as child elements, never as attributes.
Microsoft's strategy is always embrace, extend, dominate. Because so many services are needed on top of SOAP by applications, this strategy should work well with SOAP.
Most SOAP services will be private, not public for end-users. End-users need attractive, easy-to-use graphical services, as provided by HTML, not remote-procedure-call interfaces
The era of free web services is over. How will SOAP services be
paid for? There may be an initialization problem: we need reliable,
useful micropayment services in order to support the development of other
SOAP services.