What Are Web Services?
Do you know buzzword bingo? You create a bingo board and write a buzzword in each of the fields on the board. Then you attend a meeting. Whenever one of these buzzwords is used ("convergence," "synergy," and so on), you cross the field. The first person in the game with a complete line or row of crossed fields is the winner.
The field of Web services offers a whole lot of new buzzwords and acronyms. In this section, we present the most important ones so that you know what you and others are talking about when it comes to Web servicesor so that you can compete in a game of buzzword bingo.
The basic idea of Web services is machine-to-machine communication. One machine speaks to another, using standardized protocols and messages. This idea is far from new; however, in the past couple of years, global players on the market sat together and defined several underlying standards. The consequence is that you are now able to "speak" with other systems or machines without human interaction or a deeper understanding about how the other side implemented its Web service. You read the standards and follow them.
A consumer looks up a service in a directory; a provider publishes information about a service in this directory. Then, a consumer may request information from the provider, who (hopefully) happily complies. Figure 18.1 shows this connection graphically.
Figure 18.1. Service-oriented architecture.
Transport with SOAP
Transport is usually done using HTTP because firewalls are prepared for that and let HTTP traffic throughalthough some vendors of hardware firewalls started upgrading their systems to filter out unwanted Web service requests. However, do note that HTTP is not the only transport protocol possible; another one that is used (rather seldom, however) is SMTP.
Encapsulated into HTTP is SOAP. This was formerly an acronym for Simple Object Access Protocol. However, there were two problems with that name: SOAP was neither simple, nor did it have anything to do with object access. Therefore, with version 1.2 of the standard, SOAP now stands for…SOAP, and nothing else. Originally, Microsoft teamed up with Compaq, HP, IBM, and SAP and committed SOAP 1.1 to the W3C in April 2000. The XML Protocol Working Group of W3C then took over the standard; they developed version 1.2 that is a W3C Recommendation since June 2003. The SOAP extension of PHP 5 currently supports most of SOAP 1.1 and 1.2.
A SOAP message contains three parts: envelope, header, and body, similar to a letter. The envelope element is the root element of a SOAP document; header and body are its subelements (however, the header is optional and rarely used in today's applications). Following is a sample SOAP message:
<?xml version="1.0" encoding="UTF-8" ?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:php5unleashed-guid" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <SOAP-ENV:Body> <ns1:getGuid> <prefix xsi:type="xsd:string">PHP_</prefix> </ns1:getGuid> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
What happens here? We first create a SOAP envelope that is calling a service with the URN (Uniform Resource Name) php5unleashed-guid. Then we call a method getGuid and provide a parameter named prefix with value PHP.
<?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:php5unleashed-guid" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <SOAP-ENV:Body> <ns1:getGuidResponse> <Result xsi:type="xsd:string">PHP_411f663ce6ce5</Result> </ns1:getGuidResponse> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
SOAP offers much more than returning strings; among other things, user-defined data types are supported. The good thing is that you do not have to care about most of this, because the PHP SOAP module takes care of most technical things and converts data structures into their PHP counterparts.
Description with WSDL
SOAP works very well, if you know everything about the Web service. However, this is not always the case. A means to describe a Web service so that a piece of software can understand it is WSDL, the Web Services Description Language. This standard is a cooperation of IBM, Microsoft, and webMethods. These three companies had their own approaches for a Web services description standard: IBM created NASSL, Microsoft developed SCL, and webMethods conceived WIDL. The result of their collaboration, WSDL, is in its version 1.1. A W3C Noteas with SOAP, the W3C took over and developed WSDL 1.2, now a W3C Recommendation.
A WSDL description of a Web service contains all information required to use the service, including available methods and its expected parameters. This information is available in the following five elements:
All this information is stored within the root element of a WSDL description, <definitions>. Listing 18.1 shows the WSDL description for the sample Web service.
Listing 18.1. The WSDL Description for the Web Service
<?xml version='1.0' encoding='UTF-8'?> <definitions name='Guid' targetNamespace='http://www.hauser-wenz.de/Guid/' xmlns:tns='http://www.hauser-wenz.de/Guid/' xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:soapenc='http://schemas.xmlsoap.org/soap/encoding/' xmlns:wsdl='http://schemas.xmlsoap.org/wsdl/' xmlns='http://schemas.xmlsoap.org/wsdl/'> <message name='getGuidResponse'> <part name='Result' type='xsd:string/> </message> <message name='getGuidRequest'> <part name='prefix' type='xsd:string'/> </message> <portType name='GuidPortType'> <operation name='getGuid' parameterOrder='prefix'> <input message='tns:getGuidRequest'/> <output message='tns:getGuidResponse'/> </operation> </portType> <binding name='GuidBinding' type='tns:GuidPortType'> <soap:binding style='rpc' transport='http://schemas.xmlsoap.org/soap/http'/> <operation name='getGuid'> <soap:operation soapAction='urn:php5unleashed-guid#getGuid'/> <input> <soap:body use='encoded' namespace='urn:php5unleashed-guid' encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/> </input> <output> <soap:body use='encoded' namespace='urn:php5unleashed-guid' encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/> </output> </operation> </binding> <service name='GuidService'> <port name='GuidPort' binding='tns:GuidBinding'> <soap:address location='http://localhost/php/guid-server.php'/> </port> </service> </definitions>
One of the sad things about the SOAP extension that comes with PHP 5: Unlike other SOAP implementations, this one does not create the WSDL description automaticallyyet. However, this will most certainly come in future versions of PHP.
Directory Lookup with UDDI
We now know how to get information about a Web service and how to query it. Finally, we need to find such a service. For this, something similar to "Yellow Pages" exists. So-called UBRsUniversal Business Registriesare directories of Web services. Several of those UBRs exist, among them installations at IBM, Microsoft, NTT-Com, and SAP. These UBRs synchronize their data, so it is irrelevant which one you use. The current version of UDDI is 3.0; however, most implementations still use version 2. Among the companies that worked on the standard are global players such as HP, Intel, Microsoft, and Sun.
There exist two kinds of APIs to communicate with such a UBR. The Inquiry API lets you query a UBR for a service, and the Publish API lets you publish your own service to a registry. So it is probably only a matter of time until content spammers also hit this directory.
This is what an inquiry looks like:
<?xml version="1.0" encoding="utf-8"?> <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> <Body> <find_business maxRows="25" xmlns="urn:uddi-org:api_v2" generic="2.0"> <findQualifiers> <findQualifier>sortByNameAsc</findQualifier> <findQualifier>sortByDateDesc</findQualifier> </findQualifiers> <name>%guid%</name> </find_business> </Body> </Envelope>
<?xml version="1.0" encoding="UTF-8" ?> <SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/"> <SOAP:Body> <businessList generic="2.0" xmlns="urn:uddi-org:api_v2" operator="www.ibm.com/services/uddi" truncated="false"> <businessInfos> <businessInfo businessKey="DEFBD260-4CD5-11D8-B936-000629DC0A53"> <name xml:lang="en">Web Services Guided Tour</name> <description xml:lang="en">Sample Web services for Guided Tour book</description> <serviceInfos> <serviceInfo serviceKey="2A839A50-4CE1-11D8-B936-000629DC0A53" businessKey="DEFBD260-4CD5-11D8-B936-000629DC0A53"> <name xml:lang="en">Guided Tour StockQuote Service</name> </serviceInfo> </serviceInfos> </businessInfo> </businessInfos> </businessList> </SOAP:Body> </SOAP:Envelope>