Search code examples
grailsservicecontrollercommand-objects

Grails - Command object, service method


I'm not a programming savvy person, so please bear with me.

I've read blog entries and docs about command object. I've never used it and was wondering if I should. (I probably should...)

My project requires parsing, sorting, calculating, and saving results into database when users upload files.

So according to one of the blog entries I read and its corresponding github code,

1) SERVICE should receive file uploads, parse uploaded files (mainly docs and pdfs), sort parsed data using RegEx, and calculate data,

2) COMMAND OBJECT should call SERVICE, collect results and send results back to controller, and save results into the database,

3) CONTROLLER should receive request from VIEW, get results from COMMAND OBJECT, and send results back to VIEW.

Did I understand correctly?

Thanks.


Solution

  • I found this to be the best setup. Here is an example that I use on production:

    Command Object (to carry data and ensure their validity):

    @grails.validation.Validateable
        class SearchCommand implements Serializable {
        // search query
        String s
        // page
        Integer page
    
        static constraints = {
            s                   nullable: true
            page                nullable: true
        }
    
    }
    

    Controller (directs a request to a Service and then gets a response back from the Service and directs this response to a view):

    class SomeController {
    
        //inject service
        def someService
    
        def search(SearchCommand cmd) {
            def result = someService.search(cmd)
            // can access result in .gsp as ${result} or in other forms
            render(view: "someView", model: [result: result])
        }
    }
    

    Service (handles business logic and grabs data from Domain(s)):

    class SomeService {
        def search(SearchCommand cmd) {
            if(cmd.hasErrors()) {
                // errors found in cmd.errors
                return
            }
            // do some logic for example calc offset from cmd.page
            def result = Stuff.searchAll(cmd.s, offset, max)
            return result
        }
    }
    

    Domain (all database queries are handled here):

    class Stuff {
        String name
        static constraints = {
            name               nullable: false, blank: false, size: 1..30
        }
    
        static searchAll(String searchQuery, int offset, int max) {
            return Stuff.executeQuery("select s.name from Stuff s where s.name = :searchQuery ", [searchQuery: searchQuery, offset: offset, max:max])
        }
    }