Grails(10)Guide Book Chapter 9 The Service Layer
Grails(10)GuideBookChapter9TheServiceLayer
9.TheServiceLayer-ReferenceDocumentation
ServicesinGrailsaretheplacetoputthemajorityofthelogicinyourapplication,leavingcontrollersresponsibleforhandlingrequestflowwithredirectsandsonon.
CreatingaService
>grailscreate-servicehellowworld.simple
Itwillautomaticallycreateaserviceclassingrails-app/services/hellowworld/SimpleService.groovy
DefaultDeclarativeTransactions
Allservicesaretransactionalbydefault,todisablethissetthetransactionalpropertytofalse:
classCountryService{
statictransactional=false
}
GrailsalsofullysupportsSpring'sTransactionalannotationforcases.
importorg.springframework.transaction.annotation.Transactional
classBookService{
@Transactional(readOnly=true)
deflistBooks(){}
@Transactional
defupdateBook(){}
}
betterway
@Transactional
classBookService{
@Transactional(readOnly=true)
deflistBooks(){}
defupdateBook(){}
defdeleteBook(){}
}
ValidationErrorsandRollback
Acommonusecaseistorollbackatransactioniftherearevalidationerrors.
importgrails.validation.ValidationException
classAuthorService{
voidupdateAge(id,intage){
defauthor=Author.get(id)
author.age=age
if(!author.validate()){
thrownewValidationException("Authorisnotvalid",author.errors)
}
}
}
importgrails.validation.ValidationException
classAuthorController{
defauthorService
defupdateAge(){
try{
authorService.updateAge(params.id,params.int("age"))
}catch(ValidationExceptione){
defauthor=Author.read(params.id)
author.errors=e.errors
renderview:"edit",model:[author:author]
}
}
}
9.2ScopedServices
prototype-Anewserviceiscreatedeverytimeitisinjectedintoanotherclass
request
flash
flow
conversation-inwebflowstheservicewillexistforthescopeoftheconversation.
session
singleton(default)
configurethescopewiththiscode
staticscope="flow"
9.3DependencyInjectionandServices
DependencyInjectionBasics
AkeyaspectofGrailsservicesistheabilitytouseSpringFramework'sdependencyinjectionfeatures.
classBookController{
defbookService
...
}
DependencyInjectionandServices
Wecaninjectservicesinotherserviceswiththesametechnique.
classAuthorService{
defbookService
}
DependencyInjectionanddomainclasses
Wecaneveninjectservicesintodomainclassesandtaglibraries.
classBook{
…
defbookService
defbuyBook(){
bookService.buyBook(this)
}
}
9.4UsingServicesfromJava
Wehavejavainterface,allthegroovyservice.
10.Testing
AutomatedtestingisakeypartofGrails.Hence,grailsprovidesmanywaystomakingtestingeasierfromlowlevelunittestingtohighlevelfunctionaltests.
Whenwecreateacontrollerwithcommandwewillautomaticallycreateatestclassforcontroller
>grailscreate-controllercom.sillycat.simple
grails-app/controllers/com/sillycat/SimpleController.groovy
test/unit/com/sillycat/SimpleControllerTests.groovy
RunningTests
>grailstest-app
TargetingTests
>grailstest-appSimpleController
>grailstest-app*Controller
>grailstest-appcom.sillycat.*Controller
>grailstest-appcom.sillycat.*
runallthetestsinapackageincludingsubpackages…
>grailstest-appcom.sillycat.**.*
targetparticulartestmethods
>grailstest-appSimpleController.testLogin
10.1UnitTesting
10.1.1UnitTestingControllers
10.1.2UnitTestingTagLibraries
10.1.3UnitTestingDomains
10.1.4UnitTestingFilters
10.1.5UnitTestingURLMappings
10.2IntegrationTesting
SimulatingRequestData
TestingWebFlows
10.3FunctionalTesting
CanooWebtest-http://grails.org/plugin/webtest
G-Funchttp://grails.org/plugin/functional-test
Geb-http://grails.org/plugin/geb
Selenium-RC-http://grails.org/plugin/selenium-rc
WebDriver-http://grails.org/plugin/webdriver
References:
http://grails.org/doc/latest/guide/index.html
http://grails.org/doc/latest/guide/services.html
http://grails.org/doc/latest/guide/testing.html