Van Grails 2.3 naar 2.4

GrailsDeel 1: Grails, wat is er veranderd sinds oktober 2013? En wat zijn de nieuwe mogelijkheden van versie 2.4?

1. Scaffolding plugin

1.1. Is nu een eigen plugin
Tot en met versie 2.2.x van Grails was er altijd de mogelijkheid om een kickstart te maken met een Grails project. Eerst maak je de domainmodellen en dan via $ ¬grails ¬generate-all ¬”*”
maakte je de controllers en views. Sinds 2.3.x van Grails werkt dit niet meer. Nu moet je eerst de scaffolding plugin installeren voordat je deze functionaliteit kunt gebruiken. Zet daartoe in je BuildConfig.groovy de volgende regels: compile ¬”:scaffolding:2.1.1”. Nu heb je naast het gebruik van de bovenstaande commando’s ook de mogelijkheid om RESTful services te maken. Hierover later meer.


2. Controllers

2.1. Definitie REST
Representational State Transfer (REST) is een manier om het maken, lezen, bijwerken of verwijderen van informatie op een server met behulp van eenvoudige HTTP-requests een stuk makkelijker te maken dan SOAP. Het is een alternatief voor de meer complexe mechanismen zoals SOAP, CORBA en RPC. Een REST conversatie is gewoon een GET HTTP-verzoek naar de server.

2.2. Controllers zijn nu RESTful
Vanaf 2.3 van Grails worden de controllers anders gemaakt dan voorheen. In plaats van aangeven wat er gedaan moet worden om het resultaat te renderen wordt er aangegeven wat er gerenderd moet worden via het respond commando. Afhankelijk van de url waarmee de bezoeker de site bezoekt (.json, .xml, html) wordt er tijdens runtime gekeken wat Grails moet returnen. Als de url eindigt op .xml dan wordt er in plaats van de HTML pagina een XML bericht teruggestuurd met daarin het te renderen instantie van het domain object. Hiermee hebben we dus letterlijk met 1 regel code een volledige RESTful webservice.

3. Domain

3.1. @Resource annotatie in domain class
Je zou het jezelf nog makkelijker kunnen maken, hoewel dit door de Grails guru’s wel wordt afgeraden, om in je domainclass via de annotatie @Resource een RESTful webservice te maken. Ook kun je hier aangeven dat je de URL naar je domainclass anders wilt hebben dan volgens het standaard COC (Convention over Configuration) model. Bijvoorbeeld de link naar een person niet zo: http://localhost:8080/store/person/show/1 maar zo: http://localhost:8080/store/people/1 (geen werkwoorden in de url is een afspraak binnen REST)

4. Data Binding
Data Binding is vanaf Grails 2.3 volledig opnieuw gebouwd om aan de toekomstige eisen van Grails te kunnen blijven voldoen. Hierdoor zijn er een aantal dingen verbeterd met betrekking tot data binding. Een aantal voordelen staan hieronder:

4.1. Data Binding met behulp van een closure
class ¬SomeClass ¬{
¬ ¬ ¬ ¬@BindUsing({
¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬obj, ¬source ¬-> ¬source[’name’]?.toUpperCase()
¬ ¬ ¬ ¬} )
¬ ¬ ¬ ¬String ¬name
}

Omdat deze nieuwe Binding manier volledig nieuw is, kan het nog kinderziektes vertonen. Bijvoorbeeld het binden van een JSON – String [{ key:value} , { otherKey:otherValue} ] naar een java.util.List in de Grails command objecten is onbewust/bewust losgelaten. Een fix hiervoor is trouwens door te binding naar een String object in je command object en vervolgens dit te parsen via
def ¬slurper ¬= ¬new ¬JsonSlurper()
def ¬result ¬= ¬slurper.parseText(’{ ”person”:{ ”name”:”Guillaume”,”age”:33,”pets”:[”dog”,”cat”]} } ’)
Binnen Grails kun je terugschakelen naar de vorige versie van het binden door de opnemen van de volgende directives in je Config.groovy
grails.databinding.useSpringBinder ¬property ¬to ¬true ¬in ¬grails-app/conf/Config.groovy

4.2. Data binding met GORM
Je kunt nu een domeinobject als argument van een actie-methode in je controllers gebruiken. Tijdens het binden zal Grails als er een id argument wordt meegestuurd in het request proberen uit de desbetreffende database het domeinobject te fetchen. Een voorbeeld volgt hieronder:
//controller

def ¬actionMethod(Person ¬person) ¬{
// ¬if ¬person.id ¬is ¬submitted, ¬GORM ¬automagically ¬retrieves ¬the ¬person ¬from ¬the ¬DB

// ¬substitutes ¬the ¬method ¬below
}

def ¬actionMethodOld(Long ¬id) ¬{
def ¬person ¬= ¬Person.get(id)
}
Let wel op: indien je in een team werkt moet code in eerste instantie leesbaar zijn voor al jouw mede-collega’s. Dus je collega’s moeten op de hoogte zijn van de werkwijze in teams. Dit geldt voor alles uiteraard, maar zeker voor de bovenvermelde nieuwe feature.

5. Test
Hieronder een overzicht van de meest recente wijzigingen van Grails voor wat betreft testen.

5.1. Forked executie
Vanaf Grails 2.3 wordt een test op een andere JVM instance uitgevoerd dan de huidige draaiende Grails server. We hebben vast allemaal wel eens die “irritante” melding gezien dat er een interface niet kan worden gevonden of dat de code zou zijn veranderd voor de test te starten? Vanaf Grails 2.3 is dat niet meer zo omdat de Jvm altijd in een verse instantie draait. Hier hoef je niets voor te doen …. behalve dat je eventueel iets wilt doen met de geheugeninstellingen. Bij het creëren van een nieuwe Grails 2.3. applicatie krijg je automatisch al sensible defaults in je Config.groovy, zoals dit:
forkConfig ¬= ¬[maxMemory: ¬1024, ¬minMemory: ¬64, ¬debug: ¬false, ¬maxPerm: ¬256]
grails.project.fork ¬= ¬[
¬ ¬ ¬test: ¬forkConfig, ¬// ¬configure ¬settings ¬for ¬the ¬test-app ¬JVM
¬ ¬ ¬run: ¬forkConfig, ¬// ¬configure ¬settings ¬for ¬the ¬run-app ¬JVM
¬ ¬ ¬war: ¬forkConfig, ¬// ¬configure ¬settings ¬for ¬the ¬run-war ¬JVM
¬ ¬ ¬console: ¬forkConfig ¬// ¬configure ¬settings ¬for ¬the ¬Swing ¬console ¬JVM
]

5.2. Spock is nu het default test framework
Hoewel het te ver voert om hier het gebruik van Spock helemaal uit de doeken te doen kan wel gesteld worden dat Spock een enorme vooruitgang qua testen binnen Grails voortbrengt.

5.2.1. Wat is Spock?
Spock komt uit de wereld van Ruby en staat voor SPecification and mOCKing. Het is een ander paradigma dan de gebruikelijke JUnittesten die geschreven worden voor Grails en Java EE.
Het grootste verschil en voordeel is eigenlijk dat je veel meer syntactic sugar hebt om je testen te schrijven waardoor je testen een stuk duidelijker en dus makkelijker te onderhouden en uiteindelijk beter blijven. In dit geval lijkt de code voor zich te spreken … dat moet zeker zo zijn voor testers want dat zijn niet altijd programmeurs …
when:
stack.push(elem)

then:
!stack.empty
stack.size() ¬== ¬1
stack.peek() ¬== ¬elem
en wat vind je van deze??
def ¬”computing ¬the ¬maximum ¬of ¬two ¬numbers”() ¬{
¬ ¬expect:
¬ ¬Math.max(a, ¬b) ¬== ¬c

¬ ¬where:
¬ ¬a ¬<< ¬[5, ¬3]
¬ ¬b ¬<< ¬[1, ¬9]
¬ ¬c ¬<< ¬[5, ¬9]
}
Je zou bijna met een tester van beroep willen ruilen, toch?? 🙂

Meer lezen? Ga naar Deel 2 van dit artikel!

 

Onderwerpen
Actieve filters: Wis alle filters
Pageloader
PRIVACY VOORWAARDEN

Jouw persoonsgegevens worden opgenomen in onze beschermde database en worden niet aan derden verstrekt. Je stemt hiermee in dat wij jou van onze aanbiedingen op de hoogte houden. In al onze correspondentie zit een afmeldmogelijkheid