Przejdź do treści

Zapach świeżej kawy: Play! Framework

Play!Po kilku zapowiedziach i bez zbędnych wstępów zaczynamy spotkanie z Play! i nie chodzi tu wcale o jednego z operatorów telekomunikacyjnych z Polski. Play! to framework webowy, który odbudował moją wiarę w to, że Java może jeszcze być „cool”. Co mam na myśli? Czytaj dalej…

Istnieją dziesiątki setek frameworków webowych i innych bibliotek, rozszerzeń, standardów, narzędzi itd., które mają sprawić, że projektowanie „aplikacji web” (cokolwiek by to dzisiaj miało znaczyć) ma stać się łatwiejsze, przyjemniejsze, szybsze i tańsze. Oczywiście mnogość opcji i konieczność dokonywania setek wyborów wcale nie przybliża nas do tego celu. Wybrać wcale nie jest łatwo, a nawet jak się wybierze to po relatywnie krótki czasie może się okazać, że nasz wybór był kompletnie nietrafiony, bo dany framework „umarł” (pozdrowienia dla deweloperów pracujących w Apache Struts). Tak czy inaczej co jakiś czas wybrać trzeba. I chociaż zalew opcji i możliwości jest olbrzymi a ich jakość z reguły pozostawia wiele do życzenia, co jakiś czas pojawiają się prawdziwe perły. Jedną z nich moim zdaniem jest (nie do końca już nowy i świeży – ale wciąż bardzo aktywny) projekt Play!

Co w nim tak bardzo mi się podoba? Po pierwsze i najważniejsze, autorzy odważyli się zerwać z wieloma konwencjami i standardami znanymi z Java EE. Nie chodzi tu jednak o bezmyślne kontestowanie standardów, tylko o realny powiew świeżości – niedostępny niestety zwykłym śmiertelnikom zmagającym się z bestiami pokroju Weblogic, Websphere czy nawet JBoss.

Czym jest Play? Ogólnie rzeczy ujmując Play to bogata implementacja wzorca MVC połączona ze środowiskiem do zarządzania projektem i hostowania go. W skład Play wchodzi wydajny serwer HTTP, kompilator Java (aplikacje mogą być rekompilowane online, w trakcie działania), zestaw skryptów i narzędzi do zarządzania cyklem życia aplikacji, a także szereg bibliotek zintegrowanych w jedną paczkę – mamy chociażby do dyspozycji implementacji JPA 2 oraz język szablonów widoków oparty o Groovy. Ale nie koniec na tym. Play sugeruje i silnie wspiera kilka ciekawych pomysłów architektonicznych. Część z nich powszechnie stosujemy również w innych środowiskach, jednak część może wydać się dość kontrowersyjna / nowatorska.

Jednym z głównych filarów architektonicznych Play jest podejście REST i świat bezstanowy. Przez bezstanowy rozumiemy na przykład to, że w Play nie ma tradycyjnej „sesji” – czyli wydzielonego fragmentu przestrzeni na serwerze, przywiązanego do konkretnego, zalogowanego użytkownika. Dlaczego tak? Z wielu powodów. Chociażby z uwagi na łatwość skalowania tak napisanych aplikacji (request można wysłać do dowolnego węzła w klastrze – nawet do świeżo postawionego – bez potrzeby replikacji i pilnowania spójności stanu sesji). Oczywiście takie podejście ma liczne zalety, ale ma również wady, lub przynajmniej nastręcza sporo trudności. Co zrobić jeśli jednak potrzebujemy trzymać jakikolwiek stan danej sesji? Twórcy Play sugerują trzy różne rozwiązania, które najlepiej stosować razem: 1) wszystko co się da trzymać po stronie klienta, 2) używać rozproszonego cache po stronie serwera, dla którego Play ma świetne wsparcie, 3) to co koniecznie trzeba – zapisywać w bazie danych od razu.

To oczywiście nie wszystko. Na nieco niższym poziomie, w którym stykamy się z językiem Java, również mamy kilka ciekawostek. Jak już wspomniałem Play ma zintegrowany w sobie kompilator Java. Dzięki temu w czasie tworzenia aplikacji, możemy uruchomić ją raz i trzymać działającą. Zmiany dokonane w kodzie źródłowym będą widoczne w testowej wersji od razu, bez konieczności re-deploymentu, przebudowy, restartu! Co więcej a połączeniu z bibliotekami JavaAssist i ASM, Play potrafi dynamicznie wzbogacać nasz kod. Jeśli na przykład z jednej metody kontrolera (akacji) zawołamy jakąś inną akcję, w czasie runtime takie wywołanie zostanie przetłumaczone na redirect HTTP. Podobnie, jeśli zadeklarujemy publiczne pole w klasie (czego z reguły w Javie się nie robiło dotychczas) i odwołamy się do niego, Play nadbuduje automatyczne implementacje getera i setera! Podobne techniki używane są aby dodać standardowe metody CRUD do klas w warstwie modelu i kilku innych rzeczy, które sprawiają, że czujemy się nagle bardziej dynamicznie i żywo.

Warstwa modelu w ogóle jest dość ciekawie rozwiązana w Play. W odróżnieniu od popularnego w wielu miejscach podejścia „anemicznego modelu” (czyli klas encji, które nie mają żadnej logiki w sobie i budowania oddzielnej warstwy repozytorium lub managerów do obsługi tych encji), Play promuje bogaty model (gruby?). W tym podejściu cała logika związana z daną encją trzymana jest możliwie blisko tej encji. Podejście anemiczne jest często promowane ze względu na możliwość testowania jednostkowego. Mając anemiczny model, możemy zbudować jakiś rodzaj mocka warstwy dostępu do danych, ale same encje pozostawić niezmienione… i testować. Jak Play radzi sobie w tej sytuacji? Sugeruje, aby nie mockować warstwy dostępu do danych! Zamiast tego ma zintegrowaną, prawdziwą bazę danych (obecnie jest to H2) i mechanizm automatycznego wypełniania tej bazy testowymi danymi (szykujemy testowy zestaw danych, zapisany w formacie YML – czyli bogatszej wersji JSON i tyle). W ten sposób testy jednostkowe lub automatyczne testy UI (Play ma wbudowane wsparcie dla Selenium) mogą operować na ustalonym zestawie danych testowych i jednocześnie korzystać z niezmienionego, pełnego kodu aplikacji.

Co do wbudowanej bazy danych, należy jeszcze dodać, że jest ona domyślnie włączona w czasie tworzenia aplikacji (oczywiście można to zmienić) i wspiera generowanie schematu z modelu obiektowego encji. Oznacza to, że tworząc relatywnie proste aplikacje od podstaw, możemy za dużo nie martwić się o projekt bazy danych. Rozwiązanie idealne dla początkujących a także do robienia szybkich prototypów. Działającą aplikację, z bazą danych można w ten sposób postawić naprawdę szybko. Oczywiście wszystkie te magiczne udogodnienia można wyłączyć. Można też w ogóle zrezygnować z modelu w wersji proponowanej przez Play. Co więcej są dostępne dodatki integrujące aplikacji Play z modnymi ostatnio silnikami NoSQL (lub lepiej „Not Only SQL”).

Na koniec warto dodać, że Play ma również całkiem nieźle zrobione wtyczki do popularnych IDE: Eclipse, NetBeans, IntelliJ. Zyskujemy dzięki temu wsparcie dla składni plików specyficznych dla Play (konfiguracja, widoki oparte na Groovy) oraz możliwość łatwego uruchamiania aplikacji, uruchamiania zintegrowanych testów itd.

Podsumowując, Play próbuje przybliżyć świat znany chociażby z Ruby on Rails, Django i wielu innych podobnych frameworków do Javy. Takie połączenie idealnie sprawdza się przy tworzeniu małych i średnich aplikacji web, a także w prototypowaniu. Silna integracja Play z wieloma bibliotekami a także serwisami sieciowym (hostowanie w chmurze: Google AppEngine, Heroku, autoryzacja: OAuth, OpenID itd.) ułatwia rozwiązanie wielu typowych problemów, a rosnąca społeczność dostarcza wielu ciekawych dodatków i pomysłów: Play Community. Dostępna jest też spora oferta modułów dodatkowych: Play Modules. Należy również dodać, że obecnie trwają prace nad wersją 2.0, która ma dodać m.in. zunifikowaną integrację z językiem Scala (w wersji 1.x moduł Scala istnieje niejako osobno – jako oddzielny projekt).

Na koniec – jeśli chcesz zobaczyć Play w akacji, to obejrzyj poniższy filmik (dotyczy nieco już starej wersji) i przeczytaj standardowy Tutorial. Polecam! Java żyje… :)


http://vimeo.com/7087610

1 komentarz do “Zapach świeżej kawy: Play! Framework”

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

Witryna wykorzystuje Akismet, aby ograniczyć spam. Dowiedz się więcej jak przetwarzane są dane komentarzy.