|
Web ServicesThe rapidly emerging web services technology has the potential to change the way the Internet works for businesses. Browsing web pages to enter orders is fine for individuals (business-to-consumer [B2C] applications) but not for companies (business-to-business [B2B] applications). If you want to buy a few books, going to a book vendor website and punching in your requests is probably fine. But if you run a bookstore and want to place hundreds of orders a day, this is far from a good approach, particularly if you have a program that helps you track your sales and determine reorders. Grabbing the output of this program and reentering it into another application is ridiculous. Web services are meant to solve this issue: The program used to track sales can automatically create a request and send it to a web service, which can immediately return information about the order. The next step might be to ask for a tracking number for the shipment. At this point, your program can use another web service to track the shipment until it is at its destination, so you can tell your customers how long they have to wait. As the shipment arrives, your program can send a reminder via SMS or pager to the people with pending orders, issue a payment with a bank web service, and … I could continue but I think I've given you the idea. Web services are meant for computer interoperability, much as the Web and e-mail let people interact. SOAP and WSDLWeb services are made possible by the Simple Object Access Protocol (SOAP). SOAP is built over standard HTTP, so that a web server can handle the SOAP requests and the related data packets can pass though firewalls. SOAP defines an XML-based notation for requesting the execution of a method by an object on the server and passing parameters to it; another notation defines the format of a response.
SOAP will replace COM invocation, at least between different computers. Similarly, the definition of a SOAP service in the Web Services Description Language (WSDL) format will replace the IDL and type libraries used by COM and COM+. WSDL documents are another type of XML document that provides the metadata definition of a SOAP request. As you get a file in this format (generally published to define a service), you'll be able to create a program to call it. Specifically, Delphi provides a bi-directional mapping between WSDL and interfaces. This means you can grab a WSDL file and generate an interface for it. You can then create a client program, embedding SOAP requests via these interfaces, and use a special Delphi component that lets you convert your local interface requests into SOAP calls (I doubt you want to manually generate the XML required for a SOAP request). The other way around, you can define an interface (or use an existing one) and let a Delphi component generate a WSDL description for it. Another component provides you with a SOAP-to-Pascal mapping, so that by embedding this component and an object implementing the interface within a server-side program, you can have your web service up and running in a matter of minutes. BabelFish TranslationsAs a first example of the use of web service, I've built a client for the BabelFish translation service offered by AltaVista. You can find this and many other services for experimentation on the XMethods website (www.xmethods.com). After downloading the WSDL description of this service from XMethods (also available among the source code files for this chapter), I invoked Delphi's Web Services Importer in the Web Services page of the New Items dialog box and selected the file. The wizard lets you preview the structure of the service (see Figure 23.1) and generate the proper Delphi-language interfaces in a unit like the following (with many of the comments removed): unit BabelFishService; interface uses InvokeRegistry, SOAPHTTPClient, Types, XSBuiltIns; type BabelFishPortType = interface(IInvokable) ['{D2DB6712-EBE0-1DA6-8DEC-8A445595AE0C}'] function BabelFish(const translationmode: WideString; const sourcedata: WideString): WideString; stdcall; end; function GetBabelFishPortType(UseWSDL: Boolean=System.False; Addr: string=''; HTTPRIO: THTTPRIO = nil): BabelFishPortType; implementation // omitted initialization InvRegistry.RegisterInterface(TypeInfo(BabelFishPortType), 'urn:xmethodsBabelFish', ''); InvRegistry.RegisterDefaultSOAPAction(TypeInfo(BabelFishPortType), 'urn:xmethodsBabelFish#BabelFish'); end. Notice that the interface inherits from the IInvokable interface. This interface doesn't add anything in terms of methods to Delphi's IInterface base interface, but it is compiled with the flag used to enable RTTI generation, {$M+}, like the TPersistent class. In the initialization section, you notice that the interface is registered in the global invocation registry (or InvRegistry), passing the type information reference of the interface type.
The third element of the unit generated by the WSDL Import Wizard is a global function named after the service, introduced in Delphi 7. This function helps simplify the code used to call the web service. The GetBabelFishPortType function returns an interface of the proper type, which you can use to issue a call directly. For instance, the following code translates a short sentence from English into Italian (as indicated by the value of the first parameter, en_it) and shows it on screen: ShowMessage (GetBabelFishPortType.BabelFish('en_it', 'Hello, world!')); If you look at the code for the GetBabelFishPortType function, you'll see that it creates an internal invocation component of the class THTTPRIO to process the call. You can also place this component manually on the client form (as I've done in the example program) to gain better control over its various settings (and handle its events). This component can be configured in two basic ways: You can refer to the WSDL file or URL, import it, and extract from it the URL of the SOAP call; or, you can provide a direct URL to call. The example has two components that provide the alternative approaches (with exactly the same effect): object HTTPRIO1: THTTPRIO WSDLLocation = 'BabelFishService.xml' Service = 'BabelFish' Port = 'BabelFishPort' end object HTTPRIO2: THTTPRIO URL = 'http://services.xmethods.net:80/perl/soaplite.cgi' end At this point, there is little left to do. You have information about the service that can be used for its invocation, and you know the types of the parameters required by the only available method as they are listed in the interface. The two elements are merged by extracting the interface you want to call directly from the HTTPRIO component, with an expression like HTTPRIO1 as BabelFishPortType. It might seem astonishing at first, but it is also outrageously simple. This is the web service call done by the example: EditTarget.Text := (HTTPRIO1 as BabelFishPortType). BabelFish(ComboBoxType.Text, EditSource.Text); The program output, shown in Figure 23.2, allows you to learn foreign languages (although the teacher has its shortcomings!). I haven't replicated the same example with stock options, currencies, weather forecasts, and the many other services available, because they would look much the same. Figure 23.2: An example of a translation from English to German obtained by Alta-Vista's BabelFish via a web service
|
|
Copyright © 2004-2024 "Delphi Sources" by BrokenByte Software. Delphi Programming Guide |
|