O webových službách (web services) se velice často mluví jako o převratné technologii. Píše se o nich mnoho knih a mluví na konferencích. Někteří přirovnávají význam webových služeb k počátkům používání e-mailu či ke vzniku HTML stránek. Často se také mluví o webových službách jako o třetí generaci internetu.
Webové služby jsou dalším významným krokem ve vývoji distribuovaných systémů. Navazují na technologie RPC[1], DCOM[2], CORBA[3], RMI[4]. Tyto technologie umožňují volat funkci na vzdáleném systému. Na rozdíl od těchto technologií je však technologie webových služeb platformě zcela nezávislá (nezávislá na operačním systému a programovacím jazyku). Platformní nezávislost je dána použitím XML jako formátu pro vzájemnou výměnu dat.
Všechny větší softwarové společnosti v současnosti ve svých produktech webové služby implementují (IBM, SUN, Microsoft). Kupříkladu firma Microsoft na nich založila svoji novou architekturu .NET.
[1] Remote procedure calls - technologie vzdáleného volání procedur
[2] Distributed Component Object Model - technologie rozšiřující možnosti COM
[3] Common Object Request Broker Architecture - viz. http://www.corba.org
[4] Remote Method Invocation - technologie vzdáleného volání metod objektů v JAVĚ
Webové služby i webové služby s uživatelským rozhraním (WSUI) jsou postaveny na stejných technologiích. V následující kapitole bude definován pojem webové služby, vysvětlen princip webových služeb a popsány tři základní technologie, na kterých jsou webové služby (tedy i webové služby s uživatelským rozhraním) postaveny. Pro jednoduchost budou tyto technologie prezentovány na příkladu klasických webových služeb.
Z několika možných definic webové služby přijde nejsrozumitelnější tato:
Webová služba je softwarová aplikace identifikovaná prostřednictvím URI, jejíž rozhraní a vazby je možno definovat, popsat a vyhledávat jako artefakty XML. Podporuje přímou interakci s jinými softwarovými aplikacemi prostřednictvím zpráv zapsaných v jazyce XML a přenášených protokoly internetu (viz [06]).
Vývoj internetových technologií ukazuje obrázek 2.1 – „Vývoj webových služeb“.
Webové služby, stejně jako webové služby s uživatelským rozhraním, umožňují jednoduchou komunikaci mezi aplikacemi na nejrůznějších platformách. Aplikace spolu komunikují prostřednictví XML zpráv dohodnutým protokolem. Klient (dále bude používán termín konzument) pošle požadavek webové službě (dále jako producent) ve formě XML souboru. Tento požadavek producent vyhodnotí a odpověď pošle zpět konzumentovi, opět formou XML souboru.
Webové služby jsou postaveny na těchto technologiích:
Princip použití webové služby je poměrně jednoduchý. V registru webových služeb (UDDI) vybereme webovou službu, kterou chceme použít. Z popisu webové služby (WSDL), který získáme z UDDI, zjistíme bližší informace o webové službě. Pošleme této webové službě strukturovaný dotaz protokolem SOAP. Tímto protokolem také dostaneme odpověď. Strukturu dotazu i odpovědi známe z popisu služby (WSDL). Odpověď zpracujeme a zobrazíme třeba ve formě HTML stránky. Vztah SOAP, WSDL a UDDI ukazuje obrázek 2.2 – „Technologie webových služeb“.
Ke každé webové službě by měl být k dispozici její formální popis v jazyce WSDL. Existují systémy, v nichž lze přímo z WSDL dokumentu vygenerovat požadavek ve formátu XML nad protokolem SOAP. V následujících třech kapitolách budou podrobně probrány protokoly SOAP, WSDL a UDDI.
Protokol SOAP je základem webových služeb. Je to protokol umožňující volat vzdálené objekty pomocí XML zpráv. Ze všech tří standardů SOAP, WSDL a UDDI vznikl nejdříve. Jako první začala SOAP protokol vyvíjet v roce 1998 skupina firem kolem Microsoftu. Koncem roku 1999 vznikla první verze protokolu SOAP, SOAP 1.0. V průběhu následujícího roku se připojila i IBM a vznikla druhá verze protokolu SOAP, SOAP 1.1. Přestože ji konzorcium W3C[5] oficiálně nepřijalo jako standard, je dodnes nejpoužívanější. Za standard lze považovat až verzi SOAP 1.2, která má již status W3C Recommendation.
Původní účel protokolu SOAP bylo vytvořit protokol pro vzdálené volání procedur (RPC) založený na XML. Dnes je již SOAP navržen pro obecnější uplatnění než RPC. I když se nejčastěji používá v kombinaci s protokolem HTTP[6], není s tímto protokolem nijak svázán. SOAP zprávy mohou být přenášeny třeba protokolem SMTP[7]. V současné době existuje několik desítek různých implementací SOAP na nejrůznějších platformách, od C/C++, přes Javu, .NET až po Perl.
Každá SOAP zpráva je jednoduchý XML dokument. Tento XML dokument má kořenový element obálku (envelope). Obálka obsahuje další dva elementy, nepovinnou hlavičku (header) a tělo (body), jak ukazuje obrázek 2.3 – „Struktura SOAP zprávy“.
Význam těchto elementů je následující:
Nyní si ukážeme příklad klasické SOAP zprávy zaslané webové službě. Ptáme se na hodnotu akcií s kódem DIS. V těle zprávy je požadavek na volání vzdálené funkce GetLastTradePrice, která zjistí poslední známou cenu akcií s kódem DIS.
<soapenv:Envelope xmlns:soapenv= "http://schemas.xmlsoap.org/soap/envelope/"> soapenv:encodingStyle= "http://schemas.xmlsoap.org/soap/encoding/"/> <soapenv:Body> <m:GetLastTradePrice xmlns:m="Some-URI"> <m:tickerSymbol>DIS</m:tickerSymbol> </m:GetLastTradePrice> </soapenv:Body> </soapenv:Envelope>
Jak by mohla vypadat odpověď webové služby na tuto SOAP zprávu vidíme níže.
<soapenv:Envelope xmlns:soapenv= "http://schemas.xmlsoap.org/soap/envelope/"> soapenv:encodingStyle= "http://schemas.xmlsoap.org/soap/encoding/"/> <soapenv:Body> <m:GetLastTradePriceResponse xmlns:m="Some-URI"> <m:price>34.5</m:price> </m:GetLastTradePriceResponse> </soapenv:Body> </soapenv:Envelope>
Element price obsahuje hodnotu akcií s kódem DIS. Jméno elementu, GetLastTradePriceResponse, není důležité a specifikace SOAP jej nedefinuje. Je však konvencí uvádět jej jako jméno metody s připojeným řetězcem „Response“ na konci.
V předchozím příkladu SOAP zpráv nebyla pro jednoduchost zanesena žádná SOAP hlavička. Pokud ovšem přítomna je, musí se objevit jako první element elementu Envelope. Hlavička může obsahovat několik tzv. bloků hlaviček. Každý blok hlavičky musí patřit do nějakého jmenného prostoru (namespace). Každý blok může obsahovat atribut mustUnderstand. Pokud příjemce zprávy nerozumí některému bloku, kde atribut mustUnderstand má hodnotu true, musí celou zprávu odmítnout.
V následujícím příkladě hlavička s atributem mustUnderstand nastaveným na hodnotu true říká, že pokud příjemce zprávy nerozumí transakcím, musí zprávu odmítnout.
<env:Header> <t:transaction xmlns:t=http://thirdparty.example.org/transaction env:encodingStyle=http://example.com/encoding env:mustUnderstand="true" >5</t:transaction> </env:Header>
Pokud by byla hodnota atributu mustUnderstand false, znamenalo by to, že příjemce nemusí tomuto bloku hlavičky rozumět, přesto by měl být schopen zprávu úspěšně zpracovat.
SOAP používá pro identifikování jednotlivých částí XML zprávy jmenné prostory. V příkladu SOAP zprávy uvedené v kapitole „Struktura SOAP zprávy“ jsou tři uvedeny různé jmenné prostory. První z nich, http://schemas.xmlsoap.org/soap/envelope/, určuje jmenný prostor, do kterého patří obálka, hlavičky a tělo zprávy. Druhý jmenný prostor, http://schemas.xmlsoap.org/soap/encoding/, identifikuje způsob kódování přenášených dat do XML. SOAP vyžaduje, aby každá funkce byla v určitém jmenném prostoru. Funkcím GetLastTradePrice a GetLastTradePriceResponse je tedy potřeba přiřadit nějaký jmenný prostor. Jeho hodnotou musí být nějaké URI. Protože na hodnotě URI nezáleží, je zvolen řetězec „Some-URI“. Prefixy jmenných prostorů, v tomto případě soapenv a m, nejsou důležité. Mohou být nahrazeny libovolnými jinými řetězci.
Při komunikaci aplikací na různých platformách, které navíc nemusí používat stejné datové typy, je potřeba definovat způsob výměny informací. V příkladech SOAP zpráv z kapitoly „Struktura SOAP zprávy“ je uveden atribut encodingStyle. Ten indikuje, jakým způsobem se mají serializovat data použitá ve zprávě, tj. jak platformě závislá data budou vyjádřena pomocí XML syntaxe. Pro kódování dat v protokolu SOAP lze použít libovolný způsob serializace. Standard SOAP však přímo jeden definuje. Datové typy podporované standardním kódováním protokolu SOAP jsou datovými typy definované specifikací XML schémat.
SOAP definuje tři základní způsoby vyjádření datových typů. Moje jméno by mohlo být zakódováno do XML pro potřeby SOAP protokolu takto:
Datové typy definované přímo v XML zprávě.
<person> <name xsi:type="xsd:int">Martin</name> </person>
Atribut xsi:type určuje specifikaci XML schématu, ke kterému daný element patří.
Datové typy definované externím XML schématem.
<person xmlns="schema.xsd"> <name>Martin</name> </person >
XML schéma schema.xsd potom obsahuje následující definici
<xsd:element name=" tickerSymbol" type="xsd:string"/>
Datové typy definované jiným typem schématu.
Jak je vidět na příkladu SOAP zpráv z kapitoly „Struktura SOAP zprávy“, není vždy potřeba pravidla kódování definovat. Pokud příjemce zprávy ví, jak se zprávou naložit, nejsou pravidla kódování nutná. Hlavním cílem SOAP kódování je umožnit aplikacím, které si vyměňují dynamicky dokumenty, aby bez předchozí znalosti dokumentu byly schopny rozhodnout o typech dat, které přijímají.
Přestože SOAP nijak nedefinuje, který protokol má být použit pro přenos SOAP zpráv, nejčastěji se používá protokol HTTP. Důvodem je jeho rozšířenost. Také většina firewallů umožňuje většinou neomezenou komunikaci na portu rezervovaném pro HTTP protokol, takže lze tento protokol použít jako transportní protokol pro SOAP komunikaci. Právě nutnost povolovat další porty pro komunikaci byla hlavní nevýhodou technologií DCOM a CORBA. Při použití protokolu HTTP jako transportního protokolu pro přenos SOAP zpráv jsou SOAP zprávy obsaženy v těle HTTP požadavku či odpovědi. HTTP požadavek pak musí obsahovat hlavičku SOAPAction, která danou SOAP zprávu identifikuje. Protokol HTTP je také jediný transportní protokol, který je zanesen přímo ve specifikaci protokolu SOAP. Následuje příklad SOAP zprávy z příkladu z kapitoly „Struktura SOAP zprávy“, přenášené protokolem HTTP. HTTP požadavek vypadá takto:
POST /StockQuote HTTP/1.1 Host: www.stockquoteserver.com Content-Type: text/xml; charset="utf-8" Content-Length: 555 SOAPAction: "urn:StockQuote#GetLastTradePrice" <soapenv:Envelope xmlns:soapenv= "http://schemas.xmlsoap.org/soap/envelope/"> soapenv:encodingStyle= "http://schemas.xmlsoap.org/soap/encoding/"/> <soapenv:Body> <m:GetLastTradePrice xmlns:m="Some-URI"> <m:tickerSymbol>DIS</m:tickerSymbol> </m:GetLastTradePrice> </soapenv:Body> </soapenv:Envelope>
Obsah odpovědi musí být stejně jako obsah požadavku identifikován jako XML dokument pomocí příslušného MIME typu text/xml v hlavičce Content-Type. Odpověď na tento požadavek vypadá takto:
HTTP/1.1 200 OK Content-Type: text/xml; charset="utf-8" Content-Length: 450 <soapenv:Envelope xmlns:soapenv= "http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:encodingStyle= "http://schemas.xmlsoap.org/soap/encoding/"/> <soapenv:Body> <m:GetLastTradePriceResponse xmlns:m="Some-URI"> <m:price>34.5</m:price> </m:GetLastTradePriceResponse> </soapenv:Body> </soapenv:Envelope>
Při použití HTTP jako přenosového protokolu SOAP zpráv jsou používány standardní návratové kódy protokolu HTTP. Pokud se při zpracování SOAP zprávy nevyskytla chyba, vrátí protokol HTTP návratový kód 200, jak vidíme na příkladu HTTP odpovědi výše. Pokud se naopak vyskytla při vyřizování SOAP zprávy jakákoli chyba, vrátí webová služba chybový kód 500, Internal server error. V případě chyby je v těle SOAP zprávy obsažen element Fault, který popisuje danou chybu přesně podle SOAP specifikace.
Pokud chceme používat nějakou webovou službu, musíme o ní znát některé základní informace. Především potřebujeme vědět, kde se webová služba nachází, jakými protokoly s ní můžeme komunikovat a jaké operace webová služba implementuje. K tomuto účelu slouží protokol WSDL, který popisuje rozhraní webové služby. Známe-li popis webové služby, můžeme vytvořit smysluplnou SOAP zprávu. SOAP zprávu můžeme vytvořit ručně nebo automatizovanými nástroji, které z popisu webové služby SOAP zprávu vytvoří.
Protokol WSDL vznikl z potřeby strukturovaně popsat rozhraní webových služeb. WSDL je založen na XML, je tedy platformně nezávislý. O jeho vznik se zasloužili především firmy Microsoft a IBM. Protokol WSDL vznikl ze tří jazyků: NASSL, SCL a SDL. V současnosti se používá verze WSDL 1.1. Konsorcium W3C vytvořilo pracovní skupinu Web Services Description Working Group, která nyní pracuje na vývoji verze WSDL 1.2.
WSDL dokument definuje webovou službu (service) jako množinu síťových uzlů, neboli bran (port). Brána je definována znovupoužitelnou vazbou (binding) a síťovou adresou. Znovupoužitelná vazba říká, jakým způsobem se s danou webovou službou spojím. Síťová adresa určuje, kde se webová služba nachází. V každé vazbě jsou definovány operace (operation), které daná webová služba implementuje. Tyto operace jsou však nejprve popsány abstraktně a až potom jsou svázány s konkrétní vazbou. WSDL dokument se skládá ze tří hlavních částí.
Tímto způsobem také bývá často rozdělen samotný WSDL dokument. Dokument obsahující konkrétní popis služby importuje dokument obsahující abstraktní popis služby a ten pak importuje definice datových typů. WSDL dokument je tvořen několika elementy s následujícím významem:
Element typy (types) definuje datové typy používané v SOAP zprávách. Přestože WSDL protokol není svázán s žádným typovým systémem, jako výchozí typový systém je používáno XML schéma specifikace. Přestože můžeme použít libovolný jiný typový systém, specifikace XML schéma je nyní nejrozšířenější typový systém. Specifikace XML schéma definuje jednoduché datové typy jako jsou string, integer, float. Pokud hodnoty vstupu a výstupu operací definovaných v popisu webové služby jsou těmito jednoduchými typy, není potřeba element types ve WSDL dokumentu vůbec definovat.
Pokud ovšem parametrem operace webové služby není jednoduchý datový typ, musíme tento datový typ explicitně definovat v elementu types. Pokud by například některá operace vracela pole hodnot, bylo potřeba v elementu types definovat nový datový typ takto:
<complexType name="ArrayOfString"> <complexContent> <restriction base="soapenc:Array"> <attribute ref="soapenc:arrayType" wsdl:arrayType="string[]"/> </restriction> </complexContent> </complexType>
Každý nový datový typ je založen na nějakém existujícím datovém typu. Novému datovému typu můžeme definovat určitá omezení (metoda restriction) či rozšíření (metoda extension). Takto můžeme jednoduše vytvořit vlastní datový typ, který upravuje nějaký jednoduchý typ. Typickým příkladem je datový typ Handle definovaný WSDL dokumentem popisující WSRP služby.
<simpleType name="Handle"> <restriction base="xsd:string"> <xsd:minLength value="1"/> <xsd:maxLength value="255"/> </restriction> </simpleType> <element name="Handle" type="types:Handle"/>
Mapování datových typů podle XML schémat na datové typy konkrétního programovacího jazyka provádí nástroje pro webové služby.
Element zpráva (message) definuje formát předávaných zpráv pomocí dříve definovaných datových typů. Zprávy fungují jako vstupní nebo výstupní struktury pro operace. Každá zpráva má své jméno, které je v celém WSDL dokumentu mezi všemi zprávami jedinečné. Zprávu tvoří několik logických částí zprávy (message part). Každá část zprávy definuje jeden vstupní nebo výstupní parametr volané operace. Část zprávy obsahuje atribut name, který musí být v rámci jedné zprávy jedinečný. Dále musí část zprávy obsahovat atribut element nebo atribut type definující datový typ parametru operace. Příklad elementu message z WSDL popisu webové služby zjišťující aktuální hodnotu akcií uvedené v kapitole „Struktura SOAP zprávy“ je uveden níže.
<message name="GetTradePriceInput"> <part name="tickerSymbol" element="xsd:string"/> </message>
Element operace (operation) popisuje funkce implementované webovou službou. Tyto oprace abstraktně definuje element PortType. Konkrétní podobu každé operace vyjadřuje až vazba (binding). Vstupní a výstupní parametry operací definuje element message. Operace mohou být dle definice WSDL jedním z následujících typů.
Operace typu Request-response je nejrozšířenějším typem operací mezi webovými službami. Jednotlivé typy operací asi nejlépe vysvětluje následující obrázek.
Konkrétní aplikace operace GetTradePrice uvedené ve vazbě StockQuoteSoapBinding popisu webové služby:
<operation name="GetTradePrice"> <soap:operation soapAction= "http://example.com/GetTradePrice"/> <input> <soap:body use="encoded" namespace="http://example.com/stockquote" encodingStyle= "http://schemas.xmlsoap.org/soap/encoding/"/> </input> <output> <soap:body use="encoded" namespace="http://example.com/stockquote" encodingStyle= "http://schemas.xmlsoap.org/soap/encoding/"/> </output> </operation>
Element PortType tvoří abstraktní rozhraní webové služby. PortType je pojmenovaná sada abstraktních operací (operation) implementovaných danou webovou službou (service). Atribut name elementu PortType jednoznačně určuje daný typu portu.
V příkladu WSDL dokumentu je použita Request-response operace GetLastTradePrice, jejíž vstupní a výstupní parametry jsou definovány zprávami GetLastTradePriceIput (input message) a GetLastTradePriceoutput (output message). Zde je uveden element typ portu StockQuotePortType:
<portType name="StockQuotePortType"> <operation name="GetLastTradePrice"> <input message="tns:GetLastTradePriceInput"/> <output message="tns:GetLastTradePriceOutput"/> </operation> </portType>
Element vazba (binding) říká jakým způsobem jsou operace daného typu portu volány. Definuje konkrétní přenosový protokol a formát zpráv těchto operací. Vazba je jednoznačně určena atributem name. Atribut type určuje typ portu, který vazba adresuje. Zde je příklad vazby uvedené ve WSDL dokumentu webové služby:
<binding name="StockQuoteSoapBinding" type="tns:StockQuotePortType"> <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="GetTradePrice"> <soap:operation soapAction="http://example.com/GetTradePrice"/> <input> . . </input> <output> . . </output> </operation>> </binding>
Vazba se jmenuje StockQuoteSoapBinding a adresuje typ portu StockQuotePortType. Atribut transport říká, že operace uvedené v typu portu StockQuotePortType budou volány protokolem HTTP. Atribut SOAPAction definuje HTTP hlavičku SOAPAction.
Element brána (port) je koncový bod služby (service) definovaný jako kombinace síťové adresy a vazby (binding). Port je ve WSDL dokumentu jednoznačně určen svým atributem name. Atribut binding jednoznačně určuje vazbu, kterou daný port používá. Atribut soap:address určuje adresu služby (service). Existují dvě zásadní pravidla, která musí element port splňovat.
V příkladu WSDL dokumentu je definován port StockQuotePort. Tento port je volán způsobem definovaným vazbou StockQuoteBinding a adresou http://example.com/stockquote. Zde je ukázka elementu port:
<port name="StockQuotePort" binding="tns:StockQuoteBinding"> <soap:address location="http://example.com/stockquote"/> </port>
Jedna služba (service) může být zpřístupněna více branami s různými vazbami. Můžeme tedy definovat dvě brány a k nim odpovídající vazby. Jednou branou budeme se službou (service) komunikovat protokolem HTTP, druhou branou protokolem SMTP.
Služba (service) sdružuje několik bran (portů) do jedné služby. Každá služba je jednoznačně určena svým atributem name. Porty mohou v rámci služby (service) sdílet stejný typ portu PortType, musí však mít rozdílné vazby (binding) nebo adresy.
Následuje příklad části WSDL dokumentu definující samotnou službu (service).
<service name="StockQuoteService"> <documentation>My first service</documentation> <port name="StockQuotePort" binding="tns:StockQuoteBinding"> <soap:address location= "http://example.com/stockquote"/> </port> </service>
Služba se jmenuje StockQuoteService, je dostupná na adrese http://example.com/stockquote přes port StockQuotePort.
Máme-li WSDL dokument k dané webové službě, můžeme ji začít používat. SOAP zprávy můžeme psát podle WSDL dokumentu dané webové služby ručně nebo můžeme s výhodou použít tzv. invocation tools, které z daného WSDL souboru dokáží vygenerovat SOAP zprávu.
Samotný WSDL dokument můžeme také napsat ručně nebo nadefinovat pouze rozhraní služby a použít opět některého z automatizovaných nástrojů k vygenerování WSDL dokumentu. Například v .NET vygenerujeme WSDL dokument z rozhraní webové služby zadáním služba.asmx?WSDL v prohlížeči.
UDDI (Universal Description, Discovery and Integration) je standardní mechanismus registrování a vyhledávání webových služeb. Slouží jako velký adresář, do kterého mohou poskytovatelé webových služeb (třeba firmy) ukládat popisy svých služeb a informace o sobě. Uživatelé mohou v této databázi vyhledávat informace o firmách poskytující webové služby a samozřejmě také o službách samotných. Komunikace s UDDI registrem probíhá protokolem SOAP. UDDI totiž funguje jako webová služba. Databáze UDDI se nazývají registry.
UDDI protokol vznikl kolem roku 2000 jako společný projekt firem IBM a Microsoft. V současnosti jsou registry UDDI tvořeny čtyřmi následujícími entitami:
UDDI registr je používán tak, že si vyhledáme webovou službu, kterou potřebujeme a získáme její WSDL. Pokud máme WSDL dané webové služby, můžeme webovou službu začít používat. Nemáme ovšem žádnou záruku toho, že webová služba bude opravdu dělat to, co je v jejím popisu. Také si nemžeme být jisti, že autor webové služby uvedený v UDDI registru je opravdu ten, který ji skutečně vytvořil. Vyvstává tedy otázka, neexistuje-li lepší způsob vyhledávání webových služeb, kde by bylo zaručeno autorství a funkce webové služby. Takovou alternativou je novější mechanismus získávání informací o webové službě, WSIL (Web Services Inspection Language)[8]. WSIL pracuje na opačném principu než UDDI. V případě WSIL si nejprve vyhledáme důvěryhodného poskytovatele webové služby. Vybereme si webovou službu, kterou poskytuje a požádáme přímo poskytovatele webové služby o její WSDL. V současnosti je však rozšířenější protokol UDDI než WSIL. Standardizací UDDI se zabývá konsorcium OASIS[9] (Organization for the Advancement of Structured Information).
[5] Konzorcium standardizující internetové technologie, viz. http://www.w3c.org
[6] Hyper Text Transfer Protokol - standardní protokol zpřístupňující WWW stránky
[7] Simple Mail Transfer Protokol - protokol pro posílání elektronické pošty
[9] Konzorcium vytvářející standardy internetových technologií - viz. http://www.oasis.org