Shrivar R
Shrivar R

Reputation: 141

Correctly using services in Grails (per MVCS)

So I am a newbie grails developer, and was wondering how to properly use services per the MVCS design pattern. Right now in my service, I have a couple functions doing my application logic, and then I am referencing the service directly from my gsp. I read on a comment here that this is not good form. So right now I have

<g:set var="doc" bean="documentPartService"/> directly in my gsp.

So I am looking to change it, just like the comment states, by passing the information through the right channels.

One little hurdle I am coming across is passing information from my service to my controller to my gsp. For an example

<g:form name="inputForm" action="replace">
somecodehere...
<input value="Submit" type="submit">
</g:form>

then in my replace function in my controller

def replace(){
    render documentPartService.replace(params)
}

then I have some logic in my service.

I have seen in some services I have looked at, they return the variable as a json (documentBody is a variable local to my service)

return documentBody as JSON

but I am a little puzzled on how to actually access this in my controller/view. I can't just print documentBody in my controller, because it is only defined in my service. In the plugin services and controllers I was using as references, the controllers are 1 liners, just like I have, where the only thing they do is render servicefunction()

Can anyone shed some light on how I should properly design this?

Upvotes: 0

Views: 124

Answers (1)

V H
V H

Reputation: 8587

When you post your form the action is replace - the replace action in your controller renders the output of your service back out as the output rather than returning a gsp bound to the replace controller definition.

In theory it should work as in the user will post - the post will return the action replace which will return that JSON response.

the alternative is

def replace(){
    def myValue=documentPartService.replace(params)
    render (view: 'replace', model: [myValue:myValue ])
}

then you could have a gsp page called replace which has ${myValue} defined in it which will be its results.

Also its probably a better idea to call your service with defined values passed via the controller to it:

def replace(String val1,String val2,String val3){
  def myValue=documentPartService.replace(val1,val2,val3)
  [myValue:myValue ]
}

UPDATE

It may seem much coming from me to be hinting the latter method considering you probably seen the first call i.e.

render documentPartService.replace(params)

calls similar to above methods within one of my plugins.. I guess if you took a look at the mailinglist plugin, you will notice with the help of Burt. The controllers/services are locked down to data types and exact expectations.

I can only tell you from experience that best practices are if they are to be defined functions that have no reason for expansion then stick with the latter method. In the case of for example ajaxdependancyselection using the render services output method, in some ways this helps keep it more backward/forward compatible. But actually thinking about it maybe those calls can be locked down. Will update the plugin soon

Upvotes: 1

Related Questions