Marcel van Beuzekom
Eén van de nieuwe technieken die we tegenkomen in Delphi 6
is 'Web Services'. Dit artikel legt je uit wat Web Services zijn, hoe je een
server kunt maken en wat een client moet doen om met zo'n Web Service te
communiceren.
Wat zijn Web Services?
Web Services zijn objecten die gebruikt kunnen worden via een netwerk,
bijvoorbeeld internet. Web Services zijn platform onafhankelijk en
programmeeromgeving onafhankelijk. Een object geschreven in de ene taal kan dus
worden gebruikt in de andere taal. Het platform waar de server en client op
draaien is niet van belang.
Het kan zijn dat deze beschrijving je erg bekend voorkomt, het zou namelijk
ook een beschrijving van COM/DCOM kunnen zijn. Wat is er dan nieuw? Eigenlijk
niets! DCOM is alleen nooit helemaal geworden wat het zou moeten zijn, namelijk
een platform onafhankelijk systeem. Een ander nadeel van DCOM is dat het een
protocol is naast de standaard protocollen zoals http, pop news enzovoort.
Verder vereist DCOM nogal wat administratie en registratie in het netwerk, op
zich niet vreemd omdat bij DCOM de beveiliging door het besturingssysteem
gebeurd. Kortom, DCOM is zeer goed in wat het moet doen, maar multi platform is
het nooit geworden. Web Services belooft dat wel te bereiken.
Waarom zou Web Services nou wel het succes kunnen worden waar dat bij DCOM
niet helemaal lukte? De technieken die Web Services gebruiken zijn: SOAP,
HTTP, GET/POST, MIME en XML. Kortom, het is een verzameling van bestaande
technieken in plaats van een compleet nieuwe techniek. Er hoeft dus weinig te
worden geconfigureerd op de server (publiceren is voldoende) en op de client.
Ook firewalls hoeven niet speciaal te worden aangepast omdat Web Services over
standaard HTTP draaien.
Een andere mogelijke succesfactor is het feit dat het World Wide Web
Consortium heeft vastgelegd waaraan een webservice moet voldoen. Het verleden
heeft bewezen dat dat nog geen garantie is dat iedereen zich aan die standaard
houdt, denk maar aan de HTML uitbreidingen die zowel Microsoft als Netscape
verzonnen zonder dit in een standaard vast te leggen. Maar de standaard is er en
die is door een onafhankelijke partij vastgelegd.
Overigens worden SOAP en
Web Services vaak door elkaar gebruikt, dat is niet helemaal terecht. SOAP is
één van de protocollen die gebruikt kan worden voor Web Services, maar dat zou
net zo makkelijk een ander protocol kunnen zijn. Borland houdt het voorlopig bij
SOAP, wij sluiten ons daar maar bij aan.
WSDL
De standaard van W3C beschrijft onder andere dat er een Web Services
Description Language (WSDL) moet zijn. Een WSDL is een XML-document waarin
wordt beschreven wat de mogelijkheden van een Web Service zijn, het 'contract' naar
de buitenwereld. Ook hier zie je weer een overeenkomst met COM: de WSDL van een
Web Service is vergelijkbaar met de interface van een COM object.
Zonder op alle details in te gaan: er zijn dus een aantal afspraken waaraan we ons moeten houden voordat we
een Web Service kunnen gaan bouwen. Maar gelukkig zijn wij Delphi programmeurs
en, verwend als we zijn, gaan we er vanuit dat Borland dat allemaal voor ons
heeft geregeld. En uiteraard: ook nu klopt dat weer. We gaan ons dus niet te
veel meer bezighouden met de techniek, laten we maar gewoon eens een Web Service
gaan bouwen, samen met een client die daar gebruik van maakt.
De webserver
De Web Service die we gaan bouwen zal worden gepubliceerd als een CGI
applicatie. Je zult dus een webserver nodig hebben en die zul je zo moeten configureren
dat er CGI applicaties gedraaid kunnen worden. Een korte inleiding hierover vind
je in het artikel WebDelphi: introductie.
De EuroConverter
Waarschijnlijk één van de meest gebouwde routines van de afgelopen jaren:
euroconversie routines. Zou het niet handig zijn als die berekening gewoon op
één plaats stond zodat we die vanuit onze programma's gewoon konden aanroepen?
Problemen zoals: "Mag ik in één keer van NLG naar BEF omrekenen?", "Hoe
moet ik afronden?" zouden dan niet meer bestaan, die routine zou dat
allemaal zelf verzorgen. Uiteraard willen we zo'n routine vanuit alle platformen
en programmeertalen aan kunnen roepen... een webservice dus!
De Web Service
Om een nieuwe Web Service te maken kies je voor File / New / Other / Web
Services / Soap Server application. Vervolgens zie je een dialoog die je kent
van het maken van web applicaties:
We hadden al besloten dat de Web Service in een CGI applicatie zou komen, het
wordt dus de tweede keuze. Vervolgens wordt er een web applicatie gemaakt, maar
op de datamodule staan alvast een aantal componenten:
- HTTPSoapDispatcher1
- Dit component regelt het inkomende verkeer dat als requests binnenkomt
en naar interface calls moet worden omgezet. Het component registreert
zich als 'auto dispatching' object bij de webmodule zodat alle calls van
de webmodule meteen naar de SoapDispatcher worden doorgestuurd.
- Dit component regelt het inkomende verkeer dat als requests binnenkomt
- HTTPSoapPascalInvoker1
- De SoapPascalInvoker krijgt de requests van de SoapDispatcher en
stuurt ze uiteindelijk door naar de betreffende interfaces.
- De SoapPascalInvoker krijgt de requests van de SoapDispatcher en
- WSDLHTMLPublish1
- Dit is het component dat de WSDL aanmaakt voor de interfaces die we
hebben geregistreerd binnen de server
- Dit is het component dat de WSDL aanmaakt voor de interfaces die we
De datamodule die is aangemaakt is helemaal klaar voor gebruik, die sla je
dus op als MainModuleU en daar doe je verder niets aan. Het project sla je op
als EuroConvertServer.
Om de eigenlijke Web Service te maken moeten er twee dingen gebeuren: er moet
een interface worden gemaakt en een object die deze interface ondersteund.
Vervolgens moeten interface en object worden geregistreerd door middel van InvRegistry
(Invocation Registry). Dit is de plaats waar de componenten die we op de
datamodule al zagen staan gaan zoeken naar interfaces en objects.
De interface
Om een interface te kunnen registreren bij InvRegistry moet deze 'erven' van
IInvokable.
IInvokable heeft geen implementatie en erft direct van IInterface, maar IInvokable
zorgt er wel voor dat de extra benodigde RTTI (runtime type information) wordt meegelinkt in de applicatie.
In het geval van onze EuroConverter willen we de betreffende landen en
munsoorten opvragen en uiteindelijk de conversie uitvoeren. De interface ziet er
dus als volgt uit:
IEuroConverter = interface(IInvokable)
['{A83BAEB4-3F5B-4341-8027-6A874EC0D6A5}']
function Convert(Amount: Real;
FromCurrency, ToCurrency: string): Real; stdcall;
function GetCountryCount: integer; stdcall;
function GetCurrency(Index: integer): string; stdcall;
function GetCountry(Index: integer): string; stdcall;
end;
Het object
Vervolgens moet er een object
aangemaakt worden die deze interface ondersteund. Ook voor dit object is een
speciale ancestor nodig, namelijk TInvokableClass. De interface van het object
ziet er als volgt uit:
TEuroConverter = class(TInvokableClass, IEuroConverter)De verdere implementatie vind je in het EuroConverterU.pas.
public
function Convert(Amount: Real;
FromCurrency, ToCurrency: string): Real; stdcall;
function GetCountryCount: integer; stdcall;
function GetCountry(Index: integer): string; stdcall;
function GetCurrency(Index: integer): string; stdcall;
end;
De registratie
Tenslotte moeten interface en object nog worden geregistreerd, dat doe je als
volgt:
initialization
InvRegistry.RegisterInterface(TypeInfo(IEuroConver ter));
InvRegistry.RegisterInvokableClass(TEuroConverter) ;
Nu is het nog een kwestie van de unit opslaan (EuroConvertU.pas), compileren,
zorgen dat je executable in de juiste CGI directory komt en je bent klaar. Je
hebt zojuist je eerste Web Service gemaakt!
Zolang je nog geen client hebt kun je er weinig mee, maar je kunt al wel de
WSDL bekijken. Als je executable in je cgi-bin directory staat doe je dat door
het volgende adres te openen in je browser
http://localhost/cgi-bin/euroconvertserver.exe/wsdl/IEuroConverter
Je kunt ook de WSDL
op NLDelphi bekijken.
Je ziet: als je deze executable nu op een webserver zou publiceren zou
iedereen de WSDL op kunnen vragen en een programma kunnen maken dat jouw
berekeningen gebruikt.
De Client
Het maken van een server was al simpel, de client is zo mogelijk nog
simpeler. Ook hier heeft Borland de benodigde technische zaken voor ons opgelost
en kunnen we op een gewone Delphi manier onze Web Service gebruiken.
Maak een nieuwe applicatie en plaats daar een HTTPRIO component op van het
WebService tabblad. Dit component zorgt ervoor dat een WSDL document in het
geheugen wordt omgezet in een interface. Vul bij de property WSDLLocation de URL
van de WSDL in en selecteer vervolgens de Service en de Port. Het component kan
nu een verbinding maken met onze Web Service.
Interface genereren
Omdat we zojuist zelf de server hebben gemaakt zouden we onze eigen interface
kunnen gebruiken. Maar we gaan er even vanuit dat we geen kennis hebben van de
server (behalve zijn locatie) en laten Delphi een nieuwe interface maken.
Om de interface te genereren kies je voor File / New / Other / Web Services /
Web Services Importer. Bij de URL vul je het adres in dat je net hebt gebruikt
om de WSDL te bekijken in je browser. Klik op Generate en je ziet dat er een
interface wordt aangemaakt voor onze EuroConverter. Deze interface wordt dus
niet aangemaakt op basis van onze eerdere interface of ons object, maar op basis
van de WSDL. Het maakt dus niet uit in welke taal de Web Service is geschreven
of op welk platform deze draait, we kunnen van elke WSDL een interface aanmaken!
Berekenen
Zorg dat je formulier de unit met de interface used die je zojuist hebt
aangemaakt, plaats een button en in het OnClick event zet je de volgende code:
ShowMessage(FloatToStr((
HTTPRio1 as IEuroConverter).Convert(100, 'EUR', 'NLG')));
Als alles goed is gegaan zie je dat de berekening wordt uitgevoerd door je
Web Service. Ook een client applicatie die gebruik maakt van een Web Service
hebben we dus kunnen maken zonder ons uitgebreid te verdiepen in de
achterliggende techniek.
Conclusie
In dit artikel heb je gezien wat een Web Service is en hoe je die met behulp
van Delphi kunt maken en aanspreken. In volgende artikelen zal ik verder ingaan
op de mogelijkheden van Web Services en zullen we ook Web Services van anderen,
gebouwd in andere omgevingen, gaan gebruiken.
De source van de server en een wat uitgebreider voorbeeld van de client vind
je in EuroConverter.zip.
Links
Web
Services Description Language (W3C)
Gepubliceerde Web Services