22. srpna 2017

Střípky z prototypování: Wicket, Spring, REST

Měl jsem to štěstí, že jsem se teď mohl několik týdnů věnovat prototypování. Štěstí, protože je to jeden z mých nejoblíbenějších aspektů softwarového inženýrství.

Všechny prototypy vedly k cílovému, zbrusu novému řešení. V kontextu naší firmy, by to normálně dělalo oddělení R&D, ale z kapacitních a projektových důvodů to skončilo v našem delivery týmu. Rád jsem se toho ujal.

Vzhledem k tomu, že by popis řešení a implementace zabraly mnoho článků, rozhodl jsem se vytáhnout jen několik zajímavějších fragmentů z následujících témat (a i ty rozdělím do dvou-tří zápisů):
  • REST contract-first
  • Wicket + Spring
  • Wicket + REST via Spring
  • WebSockets
  • Embedded Neo4j
  • Embedded Infinispan

REST contract-first

O tomhle tématu už jsem psal v článku REST contract-first: Swagger & Gradle. Zmiňuju ho pro úplnost, ať je to na jednom místě a také protože vychází ze stejného konceptu prototypu, jako všechny následující.

Wicket + Spring

Use case

Na počátku bylo slovo: udělejte novou aplikaci. Technologie nikdo neřešil - po pravdě, existovalo rozlehlé architektonické vakuum. Tak jsem se do toho vložil a na základě tehdejších informací a kontextu jsem vybral dvě technologie: Wicket na webové GUI a Spring na "všechno ostatní".

"Všechno ostatní" zde znamená:
  • REST služby a klienti
  • Business logika
  • (Potenciálně) persistence
  • (Finálně) security

Implementace

Wicket má se Springem dobré vztahy už po léta... i když, vo-cuď-pocuď. Zkrátka, bývávalo, že jste si ze Springu vzali jen to co potřebujete. Kdepak, už je to pěkně nenažraný cvalík, který si pozve spoustu bratříčků. A skloubit ho s něčím specifickým... je docela práce.

Nicméně. Způsob, jak propojit Wicket a Spring je dvojí - jde o to, kdo koho instancuje. První způsob - kdy Wicket instancuje Springovský kontext, ze kterého je potom možné injektovat do Wicketovských komponent přes anotaci @SpringBean - je dobře popsaný ve Wicketovské Reference Guide: Integration Wicket with Spring.

Druhý způsob je flexibilnější, avšak, není nikde moc zdokumentovaný a když už, tak jen pomocí konfigurace web.xml. Funguje to tak, že WicketFilter instancuje SpringWebApplicationFactory, která prohledá Springovský kontext a instancuje Wicketovskou WebApplication. Výhodou je, že se dá injektovat přímo do Wicket aplikace, což u předešlého způsobu nejde.

Pokud chceme oželet web.xml (ano, prosím!), vypadá konfigurace filtru takto:


Prozatím pomiňme, že filter rozšiřuje JavaxWebSocketFilter (viz sekce WebSockets), obyčejný WicketFilter postačí také.

Prototype repozitory


Pokud vám to neštymuje dohromady, klíčové jsou 3 třídy:

Poučení

Tady se žádné velké překvapení nekoná - funguje to stejně dobře, jako když jsem s Wicketem a Springem pracoval před osmi lety poprvé, jen se nám oba frameworky mocně posunuly ve verzích. Snad jen, že na takovém malém prototypu se jednoduše nacvičí přepnutí z jednoho typu instancování na druhý.

Wicket + REST via Spring

Use case

Spring a Wicket nám teď pěkně kohabitují. Ale chceme přidat RESTové služby - v současnosti všudypřítomná a triviální záležitost. Ne tak docela.

Spring nabízí REST buď v rámci Spring MVC, nebo Spring Boot. Přiznám se, tady mne dost zaskočilo, že Spring nenabízí RESTové služby samostatně, podobně jako ty SOAPovské (Spring WS). Nejsem expert na Spring, takže mi nejspíš něco schází, ale zatím to vidím, že dostává na frak buď modularita, nebo snadnost použití. Přitom jediný, co vlastně potřebuji je DispatcherServlet.

K tomu use casu - potřeboval jsem dedikované URL pro REST, které by neobsluhoval Wicket a zpracovávat/produkovat JSON zprávy.

Implementace

Řešení přišlo ve dvou krocích - zaregistrovat DispatcherServlet a podstrčit JSON mapování (z nějakého důvodu to Spring nedělá out-of-the-box). Dobral jsem se k řešení, které je sice funkční, ale rozhodně ne elegantní a možná i špatný design. (Zde bych byl vděčný za jakékoliv navedení na "správnou cestu".)

Zaregistrova DispatcherServlet jen tak přes @WebServlet annotaci mi nešlo - lítaly z toho tuny výjimek, protože ve Springovském kontextu chybělo spousty věcí ze Spring webové aplikace. Všechno to, co vám tam přidá anotace @EnableWebMvc. Tudy cesta nevedla.

Vyřešil jsem to dynamickým zaregistrováním servletu přes ServletRegistration, když jsem si přes Wicket vytáhnul ServletContext:


Druhý problém - přesvědčit Spring, aby chroustal JSON - mám vyřešený jen zpola: sice "zázračně" zafungovalo angažování komba AnnotationMethodHandlerAdapter a MappingJackson2HttpMessageConverter. Bohužel, je první třída @deprecated a to já nesnáším (pokudn není zbytí).

Spring doporučuje migrovat na RequestMappingHandlerAdapter, jenže k tomu chybí jakákoliv dokumentace a Google mlčí. Moje otázka na StackOverflow je také bez odpovědi.

Řešení, na které nejsem hrdý (účel světí prostředky):


Prototype repozitory


Klíčové třídy:

Poučení

Spring je fajn. Ale přijde mi po těch letech, že je míň flexibilní a narostl do stejného molocha jako Java EE. Pokud potřebujete něco specifického, budete se brodit Springovskými výjimkami a zoufale prohledávat StackOverflow. Mimochodem, další moje StackOverflow otázka o Springu je také nezodpovězena.

Říkám si, jestli to za to stojí, se přehrabovat tak hluboko ve vnitřnostech Springu, aby člověk implementoval relativně jednoduché věci. Trochu mi to zavání vendor lock-in: dobře si rozmyslet, jestli stavět heterogenní aplikaci, nebo použít homogenní Spring.

Příště

V pokračování střípků se podíváme na WebSockety a jak do "standardní" webové aplikace přidat "reactive-like" chování.

Repository všech prototypů


Související články


1. srpna 2017

Šest ctností softwarového inženýra

Čteme teď s dětmi výbornou knížku Buddhovy pohádky na dobrou noc. Kromě pohádek samotných je v úvodu knihy několik krátkých kapitol o tom, co je to Buddhismus, kdo byl Buddha apod. Tam mi padla do oka kapitola Šest ctností (pāramitā) a okamžitě mi začaly naskakovat paralely ze softwarového inženýrství.

1. Dána

Touha dávat každému, aniž bych očekával odměnu.
Moje subjektivní zkušenost bloggera je, že máte jen minimální zpětnou vazbu na své psaní a když už nějaká je, tak je neobjektivní - pokud nepíšete úplné blbosti, tak vás (zlomek) lidí buď pochválí, sem tam nějaký ten troll, nebo spam a občas vás někdo upozorní na chyby a nesrovnalosti.

Zkrátka, obsah blogu si žije svým životem a vy to nemůžete nijak ovlivnit. Pořád ještě žiju v iluzi, že občas mé psaní někomu pomůže, nebo ho aspoň pobaví. Není to jediný aspekt mého psaní, ale právě potřeba unilaterálního sdílení je silně přítomna.

Ze stejného ranku je také obecně knowledge sharing. Krystalickým příkladem je potom open source. Možná, že někdo publikuje svůj kód, protože očekává nějaké sociální benefity, třeba uznání. Ale řekl bych, že většinou je to záležitost kultury a osobního přístupu.

2. Šíla

Rozvíjení mravného chování.
Možná už jste to zažili - přišel za váma projekťák, či jiný manažer a (v lepším případě) vás požádal, nebo vám přímo přikázal něco, co je nemorální. Možná jen trošku, možná za hranicí slušnosti a možná i něco, co je polo/ne-legální.

Možná jste byli v týmu, který nebyl přátelský k ostatním stakeholderům. Možná ani ke členům vlastního týmu.

Nevytáhnu žádné eso z rukávu, jak tyhle věci řešit. Můžu potvrdit, že je to těžké, obstát se ctí. Abyste se za to nemuseli další léta stydět.

3. Kšánti

Trpělivost a schopnost zůstat klidný, zejména v problematických situacích.
V IT se točí hodně peněz. Možná jste dělali něco pro nějakou banku, nebo evropský/mezinárodní/globální projekt, kde šlo o miliony $/€. Když pak dojde na lámání chleba, lidi dokážou pěkně zdivočet.

A nemusí jít jen o velké peníze. Někdy stačí jen nevraživost v kanceláři, či spor o to, jestli se bude větrat, nebo pouštět klimatizace.

Tváří v tvář takovým malým a velkým problémům se pak poznají profesionálové a leadeři. A vlastně... zralí lidé. Kteří neztrácejí ze zřetele, proč jsou tady a co je cílem (projektu, schůzky apod.) a situaci věcně řeší. Nenechají se strhnout emocemi.

A ví, že některé věci potřebují čas. Však to znáte - žádný projekt/produkt nevyrostl přes noc.

4. Virjá

Nadšené úsilí, které podněcuje sílu a vytrvalost, jež jsou nezbytné pro pokračování na cestě bódhisattvy.
Projekty můžou být krátké a dlouhé. Produkty mají životnost ještě delší. Být smysluplným přispěvatelem v takové práci je běh na dlouhou trať. Ne náhodou beru maraton (a trénink na něj), jako dobrou paralelu softwarového projektu. Přijdou těžké chvíle, to je realita. Co vás z toho vytáhne, je motivace. Proč to děláte?
Winners never quit and quitters never win. ~ Vince Lombardi

5. Dhjána

Koncentrace nebo meditace, která rozvíjí duševní schopnost pevného záměru, aby naše činění přinášelo lepší výsledky.
Tak pravda, tady to asi úplně nesedí. Ale máme třeba coding kata. A určitě spoustu z vás kóduje po večerech, či po nocích, zkrátka ve svém volném čase. A pokud se u toho dostanete do flow, je to vlastně práce jako meditace.
Work is valuable. It will bring humbleness and silence. ~ Osho

6. Pradžňá

Moudrost, nejen coby intelektuální porozumění, ale také schopnost přímého vhledu do pravé podstaty skutečnosti.
Ve svém jádru je softwarové inženýrství velice racionální a opřené o data. Pokud opravdu dobře rozumíte nějakému jazyku, knihovně, frameworku, víte, jak to uvnitř pracuje. Ale svět projektů je daleko rozsáhlejší a nikdo ho není schopen obsáhnout v jeho celistvosti - znáte to podobenství o slepcích a slonovi.

Čím více je člověk expert v nějaké oblasti, tím více má vyvinutou intuici. Tedy - přímý vhled do problému. Vede k tomu dlouhá, trnitá a klikatá cesta.

Cesta bódhisattvy

Ne nadarmo se ultimátnímu odborníkovi v IT říká guru. Guruem se člověk nerodí, ale postupně stává. Cesta bódhisattvy (někdo, kdo odložil vlastní osvícení, aby pomohl druhým dosáhnout stejného stavu) může být jední ze způsobů, jak se na tuto úroveň dostat.

Související články