Nico
Nico

Reputation: 3569

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 ?

Upvotes: 0

Views: 1177

Answers (2)

Uday
Uday

Reputation: 629

Constraints like unique which needs to validated from database cannot be applied on command object. In this case you can use validator http://grails.github.io/grails-doc/2.5.1/ref/Constraints/validator.html.

You can also use importFrom constraint to have all the constraint form User domain to command object http://grails.github.io/grails-doc/2.5.1/guide/validation.html.

Upvotes: 0

Uday
Uday

Reputation: 629

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.

Upvotes: 2

Related Questions