13 września 2009

Ciekawostki Grails z książki "Grails 1.1 Web Application Development"

Podczas lektury ostatniej książki o Grails - Grails 1.1 Web Application Development (której moją recenzję można przeczytać w Book review: Grails 1.1 Web Application Development) - zaintrygowała mnie wzmianka nt. Stripes. Jestem w trakcie czytania kolejnej książki o Grails i tam również trafiłem na Stripes. Mam wrażenie, jakby w tym szkielecie aplikacyjnym było coś, co podobnie jak w Wicket sprawia, że jest to całkiem ciekawe rozwiązanie, ale brakuje mu po prostu rozgłosu. Chyba kolejny raz potwierdza się reguła, że dobre samo się nie obroni i potrzeba trochę PRu, aby zademonstrować jego siłę. Pamiętam wystąpienie Jacka Lisa o Stripes, ale było to tak dawno, że nie ukrywałbym swojego zainteresowania, gdyby ktoś zechciał przedstawić go jeszcze raz w ramach spotkań grupy Warszawa JUG.

Jednej z rzeczy, na którą wcześniej nie zwróciłem uwagi było wyświetlanie wyłącznie 6 kolumn klasy dziedzinowej przy użyciu rusztowania (ang. scaffolding) w Grails. Krótki przykład jak najbardziej na miejscu. Zaczynamy od grails create-app barfaw, później cd barfaw, a dalej już pozostaje grails create-domain-class pl.jaceklaskowski.Uzytkownik, edycja klasy i dodanie więcej niż 6-ciu pól do niej, stworzenie kontrolera UzytkownikController (grails create-controller pl.jaceklaskowski.Uzytkownik) i włączenie rusztowania (niezapominając o skasowaniu akcji index), aby ostatecznie uruchomić aplikację poleceniem grails run-app.

(dla zainteresowanych: barfaw to taki na prędce sklecony skrót od BARdzo Fajna Aplikacja Webowa).

Co mnie niezwykle mile zaskoczyło, to fakt, że Grails 1.2-M2 przychodzi z całkiem nową, domyślną szatą graficzną. Niezwykle odświeżający widok.

Dodatkowo Grails chodzi domyślnie na Apache Tomcat! Wiedziałem, że w planach jest uruchomienie Grails na Tomcacie, ale sądziłem, że to jeszcze trochę potrwa. Co za niespodzianka! Mam wrażenie, że gdybym przeczytał Release Notes do tej wersji mógłbym poznać kilka innych ciekawostek, a tak pozostawiam ich spotkanie przypadkowi.

Dowiedziałem się również, że na szczycie hierarchii obiektów w Groovy stoi interfejs groovy.lang.GroovyObject z klasą abstrakcyjną groovy.lang.GroovyObjectSupport. Chcesz być obiektem Groovy a żyjesz na Javie? Wystarczy odpowiednia implementacja.

W końcu również udało mi się przez przypadek znaleźć rozwiązanie dla kwestii aktualizacji Grails bez konieczności aktualizacji wtyczek. Wystarczy zdefiniować zmienną grails.project.plugins.dir w grails-app/conf/BuildConfig.groovy i od tej pory wszystkie wtyczki trafią do wskazanego katalogu. Domyślnie wtyczki są umieszczane w katalogu zależnym od wersji Grails (w ścieżce katalogów jest numer wersji), więc wystarczyła zmiana Grails, aby całą instalację wtyczek zaczynać od nowa. Znając rozwiązanie, już nie.
 jlaskowski@work /cygdrive/c/projs/sandbox/barfaw
$ cat grails-app/conf/BuildConfig.groovy
grails.project.plugins.dir="c:/apps/grails-plugins"

jlaskowski@work /cygdrive/c/projs/sandbox/barfaw
$ grails install-plugin jsecurity
Welcome to Grails 1.2-M2 - http://grails.org/
Licensed under Apache Standard License 2.0
Grails home is set to: c:/apps/grails

Base Directory: C:\projs\sandbox\barfaw
Running script c:\apps\grails\scripts\InstallPlugin.groovy
Environment set to development
Reading remote plugin list ...
Reading remote plugin list ...
Installing plug-in jsecurity-0.4.1
[mkdir] Created dir: c:\apps\grails-plugins\jsecurity-0.4.1
[unzip] Expanding: C:\Documents and Settings\jlaskowski\.grails\1.2-M2\plugins\grails-jsecurity-0.4.1.zip
into c:\apps\grails-plugins\jsecurity-0.4.1
Executing jsecurity-0.4.1 plugin post-install script ...
Plugin jsecurity-0.4.1 installed
Plug-in provides the following new scripts:
------------------------------------------
grails create-auth-controller
grails create-db-realm
grails create-ldap-realm
grails quick-start
Kolejną ciekawostką było przedstawienie różnicy między jawnym definiowaniem typu a użyciem def przy deklaracji pól obiektu, do których zostaną przypisane instancje usług (dzięki mechanizmowi DI). Niby niewinnie wyglądająca deklaracja

def fileService
nie różni się wiele od

FileService fileService
ale w pierwszym przypadku każdorazowa zmiana implementacji FileService będzie automatycznie przeładowana i ponownie przypisana, podczas gdy w drugim przypadku przypisanie nastąpi tylko na początku, a każda kolejna zmiana wymagała będzie ponownego uruchomienia (przeładowania) aplikacji. Zaletą tego drugiego jest wsparcie IDE przy rozwiązywaniu typu zmiennej i tym samym możliwość podpowiadania możliwych metod. Wybór należy do Ciebie.

Kolejna ciekawostka znaleziona w książce to nowe mapowanie usług RESTowych w Grails 1.1 przez resource, np.:

"/api/message/$id?"(resource: "api")
Wystarczy jedynie stworzyć kontroler ApiController, aby metody GET, PUT, POST oraz DELETE były automatycznie kierowane do akcji show, update, save oraz delete. Niewielka zmiana, a ile zaoszczędzi czasu podczas prototypowania (przynajmniej, a kto wie, czy nie w finalnej wersji aplikacji?).

Na koniec ciekawostek z książki padła wzmianka o Google Web Toolkit oraz Wicket. Niestety, ale poza wzmianką niewiele więcej. Ich zaletą jest uproszczone testowanie widoku, co nastręcza dużych trudności przy zastosowaniu GSP. Ostatni komentarz Graeme Rocher do wątku "Wicket plugin and Grails 1.1" na liście dyskusyjnej Grails nie pozostawia jednak złudzeń:

The Wicket plugin needs updating for 1.1, I decided to progress too much further with it until Groovy supports anonymous inner classes and nested classes

i dalej:

> Thx for your response, any idea when Groovy is planned to support anonymous inner classes?

Groovy 1.7


Jeśli miałbym wybierać między GWT a Wicket, to w przypadku integracji z Grails postawiłbym obecnie na GWT. Ale tylko do wersji Groovy 1.7.