Controllers and Data Binding

Harry · 13 Sep 2026 · 3 views

The Role of Controllers

Controllers bridge user input, business logic, and persistence. They read request params, delegate work to services, and produce a response. Keep them thin.

Actions and URLs

class UserController {
    def index() {
        render "User Home"
    }
}

index is the default action. URL mappings can be customized:

static mappings = {
    "/users"(controller: "user", action: "index")
}

Accessing Params

def save() {
    println params.username
}

params combines query parameters, form data, and URL variables into one map-like object.

Automatic Data Binding

Grails binds request params directly onto a domain object:

def save() {
    def user = new User(params)
    user.save()
}

This is extremely powerful, which is exactly why you must control what gets bound. Never trust client input blindly.

Command Objects (Best Practice)

Command objects give you safe, validated data binding:

class UserCommand {
    String username
    String email

    static constraints = {
        username blank: false
        email email: true
    }
}
def save(UserCommand cmd) {
    if (cmd.hasErrors()) {
        flash.error = "Validation failed"
        redirect action: "create"
        return
    }
    userService.register(cmd)
    redirect action: "index"
}

Binding to Existing Objects

def update(Long id) {
    def user = User.get(id)
    bindData(user, params)
    user.save()
}

Rendering and Redirects

render "Hello Grails"
render user as JSON
render view: "create", model: [user: user]
redirect action: "index"

Restricting HTTP Methods

static allowedMethods = [
    save: "POST",
    update: "PUT",
    delete: "DELETE"
]

RESTful Controllers

class UserController extends RestfulController<User> {
    static responseFormats = ['json']
}

Common Mistakes

  • Heavy business logic in controllers.
  • Blindly binding every request param to a domain object.
  • Ignoring validation errors.
  • Not restricting HTTP methods.

Key Points

  • Controllers stay thin and delegate to services.
  • Command objects validate input safely.
  • bindData gives controlled binding for updates.
  • Restrict HTTP methods to match the operation.

Controllers and Data Binding diagram

Share this post:

Comments (0)

Please login or register to comment.