Search code examples
grailscommand-objects

Command object only in controller or could it be passed to service layer?


In Grails framework I saw the command object pattern but its use is not very clear for me. In addition most of examples given by Grails documentation are about domain classes not command objects (maybe to simplify code example).

1 - Command object is something used between view and controller layer and must stay there ?

2 - Or is it a good practice to pass command object to service layer ?

To illustrate point 2 :

class MyController {

    def updateUserPassword (UserPasswordCommand cmd) {
        ...
        myService.updatePassword(cmd)
        ...
    }
}

If point 2 is a bad practice, then how do you pass submitted data to the service layer ? Via domain class ? EDIT : Seems OK

[EDIT]

If I use command object and not domain class what to do in this case :

def signup(UserCreateCommand cmd)
{
    if (!cmd.hasErrors()) {
            def userInstance = userService.signup(cmd)
        }
    }
    if (cmd.hasErrors()) {
        /* Stay on form in order to display errors */
        render(view:"/app/authentication/_signupForm", model:[userCreateCommand: cmd])
        return
    }
    ...
}

what happen if when user service transaction ends, there is an exception raided by database (because of flushing data not respecting schema constraints) ?

The problem in my point of view is that there are two queries :

Firstly - when call cmd.hasErrors() there is a persistent call for unique constraint on email for example

Secondly - when service transaction ends, there is a flush to DB (which result in one SQL insert in my case), and maybe raises an exception on column email which has unique constraint

Test cmd.hasErrors() doesn't prevent the case where DB raises a violated constraint unique exception or I'm wrong ?


Solution

  • That's the best way to pass request params to service layer. I have seen people passing params to service which is really a worst practice. Our controllers should be dump, Max 5-8 LOC in controller method is a guideline in my company.

    Command object gives you so much power out of the box like validation, method etc.