– – where be dragons



– – where be dragons

0 0


gum-2013-where-be-dragons

GroovyMN August 2013 Presentation Slides

On Github aaronhanson / gum-2013-where-be-dragons

where be dragons

pragmatic grails development

GroovyMN August 2013

Uses For Grails

Rapid Protoype Development

grails generate-all

Enterprise Development

grails install-templates

grails create-controller

setProperties() & command objects

DataBinding Docs Link

def user = User.get(id)user.properties = params

slightly better

def userCommand = new UserCommand(params)def user = User.get(id) // still insecure probablybindData(user, params)

Grails 2.3 (new, but similar)

@Transactionaldef update(User user) {    ....    user.save flush:true    ....
}

Fat Controllers

Not always a bad thing.
Prototyping or future legacy code?
Is it used anywhere else?
Maybe OK then. Refactor later.
In larger applications it's unlikely to be a good thing.

Making Database Calls In The View Layer

Prototyping you might do this:

<g:select name="states" from="${State.list()}"/>

But you should probably do this instead:

class FooController {    def list() {        // ...        [states: States.list()]    }}
<g:select name="states" from="${states}"/>

GOTCHA!

 <g:each in="${customer.phoneNumbers.sort()}" var="phoneNumber">

GSPs

Use more templates

Use more taglibs

Be mindful of the need to

.encodeAsHTML()

.encodeAsURL()

g:* tags will do it for you

roll your own or output from model directly,

 you're own your own

Domain vs Concept 

Controllers/Services

OK For CRUD Applications

ProductController

ProductService

Product

Better For Other Applications

CatalogController

ShoppingService

Making everything a service

You're lazy. So am I.

Why do we often create services for everything?

class FooService {    def barService    ...} 

Not everything needs to be a service. 

Libraries with good old fashioned functions are OK too.

src/groovy

Try to keep your app out of your libraries.

smart domains

Quit using your domain classes as services.

Domain instances should operate on the things they know about.

If you need to look up information or do more logic, use a service.

Services are good to funnel calls and add things like caching.

Think about DomainClass.* as DB.* 

Foo.executeQuery('select * from Bar where id = 1')

Doesn't have anything related to Foo. Smell.

Injecting services in your domains

Why?

Is it really a service or is it a library?

Perhaps you're trying to do too much?

Testing can be difficult

Code coupling possibility higher

Making Everything Transactional

Stop it!

custom urlmappings

<g:link>
doesn't always do what you think if you have
multiple mappings to the same thing
order is important, as is length
naming them can help
Be careful with relative and absolute links.
You'll probably be deployed behind a reverse proxy
and can run into issues with link generation.

testing

phases vs test type

unit - fast

integration - slow

functional - slow

Quit writing unitegration tests

(yes I made up a word)

dbcreate vs migrations

dbcreate
great for development
painful for QA (w/o bootstrap)
careful with create/update options vs create-drop
migrations are better for:
deployment
keeping developers in sync
making sure that you don't forget something
(although you still could)
If you can choose, just do auto-migration.
It's just plain easier than running them separately.

Time Left?

Package naming/Plugins

Questions/Heckling?