calebds
calebds

Reputation: 26228

GSP vs. Controller in Grails

I have some experience maintaining Grails apps; now creating a "task management" application as an exercise.

Apparently there is a view dichotomy of Groovy Server Pages versus Controller actions that render a view, as evidenced by this snippet from a URLMappings.groovy example:

static mappings = {

    // ..

    "/" (view:'/index')
    "/login/$action?" (controller: 'login')
    "/logout/$action?" (controller: 'logout')

    "500" (view:'/error')
}

where user-facing URLs must be mapped to either views (GSPs) or controllers rendering a view, e.g.:

class LoginController {

    /**
     * Show the login page. 
     */
    def auth = {

        // .. auth logic

        String view = 'auth'
        String postUrl = "${request.contextPath}${config.apf.filterProcessesUrl}"
        render view: view, model: [postUrl: postUrl, rememberMeParameter: config.rememberMe.parameter]
    }

}

From a design perspective, how do I choose which method to use? When do I create views with GSPs/taglibs like typical server pages outputting HTML, and when do I map a URL to a controller that renders through a delegate GSP? Can I combine both approaches? Have I oversimplified the options here?

Upvotes: 0

Views: 478

Answers (2)

OverZealous
OverZealous

Reputation: 39570

To add to what hvgotcodes said, related to your question, the only time you'd want to map directly to a GSP view is when that view is effectively "static".

By static I mean that it isn't relying on the database or any real calculations for rendering the view. It can still be dynamic in that it relies on tag libraries for dealing with common elements, and things like the "Welcome user" text at the top of pages.

As soon as you want to deal with user-supplied input, looking up database information, manage more complicated URLs, or include calculations, you should be using a controller.

The end goal is that GSPs only contain visual and layout information, as well as the occasional static block of text. But you should always avoid mixing any logic in with the GSP, because it clutters the code and always leads to maintenance headaches later on.


Edit regarding Tag Libraries:

As I wrote below:

Tag libraries are for any logic that is connected to the view, like looping over elements, or toggling the visibility of something. Whenever you are tempted to put code directly into your GSP, it probably should be put in a tag library. Of course, there are always exceptions for one-offs.

So, if you have logic code in your view, that specifically relates to visual or layout content, that should be put in a tag library. A good example is the <sec:ifLoggedIn> tag from Spring Security Core, which can be used to toggle the visibility of an element if the user is logged in. This is much better than writing it manually like so:

<sec:ifLoggedIn>blah blah</sec:ifLoggedIn>
<g:if test="${session.user?.loggedIn}">blah blah</g:if>

Because it makes the purpose clearer (by its title), as well as abstracting the logic away, so if you later need to change the way something works, you only have to change it in one place.


tl;dr:

  • GSPs - Simplified "static" content
  • Tags - Reusable dynamic components specifically for visual or layout content
  • Controllers / GSPs - dynamic content

Upvotes: 3

hvgotcodes
hvgotcodes

Reputation: 120258

I don't think it's a dichotomy. GSPs and Controller actions (are intended to) work in tandem, the controller invoking services to load data in preparation for passing that data to the appropriate GSP.

The url mapping stuff is for if you want to break the Grails convention for urls, which is orthogonal to how loading data and displaying data (are supposed) to work.

The only time (IMHO) there is a dichotomy is when developers in a project code functionality inconsistently; i.e. it is certainly possible to give the appearance of a dichotomy.

Upvotes: 1

Related Questions