Vzpomínám si na historku, kterou mi vyprávěl můj bratra­nec, toho času majitel stavební firmy. Vyhodil z kabiny bagristu, který tvrdil, že to nejde, sedl si tam sám a ukázal, že to jde. Tohle já jsem napos­ledy neudělal, takže alespoň tímto článkem to chci odčinit.

Webové služby obvykle využívají HTTP proto­kol, který je bezsta­vový. Jeho stavo­vost dokážeme zajistit pomocí session. Když zajis­tíme stavo­vost proto­kolu, dokážeme zajistit i stavo­vost webové služby. Tak jako vám v USA nepro­dají střelnou zbraň okamžitě, ale musíte přijít až za několik dní, abyste s ní v afektu nespáchali zločin, i tady je potřeba se důkladně zamys­let, zda jo to dobrý nápad. Řekněme, že my jsme pádný důvod měli.

Java server

Není obtížné najít návod na Java stateful web service server. Nicméně je nešikovný v tom, že si manuálně musíte spravovat svůj objekt v HttpSession, ke které se musíte dostat přes WebServiceContext. Jsem vnitřně přesvědčen, že to jde vždycky udělat lépe a šlo to i tentok­rát. Ostatně na co máme SessionScope a depen­dency injection?

Java klient

Aby klient s takovou službou dokázal fungo­vat, stačí v Javě podle návodu jedno­duše přidat následující.

((BindingProvider)port).getRequestContext().put(BindingProvider.SESSION_MAINTAIN_PROPERTY, true);

C# klient

V C# to bylo složitější z toho důvodu, že jsem jako javista dostal odpověď, že to nejde. Propra­coval jsem se ke klíčovému slovu CookieContainer, ale to zname­nalo vracet se ke starší verzi jejich frameworku. Alespoň nás to přivedlo na stopu a ke koneč­nému řešení už byl jen krůček. Progra­mově nastavíte násle­dovně. Zle pocho­pi­telně zapnout i v xml konfi­gu­račním souboru bindingu.

SoapUI klient

K testování webových služeb nejspíš používáte nástroj SoapUI. A ani tam není stavová webová služba problém. Stačí si do hlaviček session přidat. Pro ilust­raci přikládám screeshoty.

Contract First

Archi­tek­to­nická odbočka. Stále ještě ne všichni vzali za své, že správný způsob tvoření webových služeb je contract first, tedy sepsat wsdl (kont­rakt) a z toho teprve generovat kód. V oblibě je pro programátory pohod­l­nější varianta: nabušit kód a z toho mi přece něco vyleze.

Spring framework považuji za úžasnou školu softwa­rového designu. Prohlašují, že jediný správný způsob je contract first, a proto Spring přístup code first vůbec nepod­po­ruje. Vybírám argumenty z jejich dokumen­tace, konkrétně kapitoly Why Contract First.

Nejdůležitějším úkolem webových služeb je jejich inter­o­pe­ra­bi­lita: podpora více platforem jako Java, .NET, Python, PHP atd., které mají různé knihovny, takže je potřeba používat něco, co mají společ­ného, a tím je XML. Třeba TreeMap nemá v XML žádný standard a každý jazyk by si to generoval po svém. Nemluvě o datu. Další třešničkou jsou třeba cyklické grafy, které by v XML vedly k rekurzi.

Pokud generu­jete wsdl z kódu, jak zaruč­íte, že se vám kontrakt nezmění? Občas je potřeba rozhraní služby změnit. V Javě pak typicky vytvoříme intefrace MyService2 a k tomu imple­men­taci. Stará služba musí pocho­pi­telně ještě běžet kvůli klien­tům, kteří doposud nezmigrovali.

V contract first přístupu je slabá vazba (looser coupling) mezi kontraktem a imple­men­tací, což nám umožňuje mít obě verze v jedné třídě. Můžeme například použít XSLT trans­for­mace staré zprávy do nové.

Stejně jako má ORM problémy s mapováním relač­ních databází na objekty, tak podobné problémy má i XML. Věci nejsou tak jedno­duché, jak se zdají. Je velký rozdíl mezi hierar­chickou struk­turou XML a grafovým Java modelem. V XSD lze rozšířit data tak, že zavedete nějaké restrikce, třeba regulární výraz ke stringu, něco takového vám Java neumožní.