Restful Web Services in Grails 3

by Jenn Strater @jennstrater



Previous Versions

Gr8Conf EUSource |Slides

About Me


About Me



About Me

Minneapolis, MN

    Connect on Social Media
  • Twitter @jennstrater
  • LinkedIn
  • Github

Pet Mom & Foster

Pumpkin Halo Gia
Curly Juliet Elway


  • Remedial REST
  • 10 Ways To Improve A RESTful API
    • with Grails Examples
  • Example

What this talk will NOT cover

  • Performance and Scaling
  • Security
  • Ingesting RESTful APIs
  • Documentation
  • Testing

Remedial REST


Described in Roy Fielding's PhD dissertation in 2000

Fielding, Roy. Architectural Styles and the Design of Network-based Software Architectures. 2000.


REpresentational State Transfer (REST) is an architectural style that describes how distributed data objects, or resources, can be defined and addressed, stressing the easy exchange of information and scalability.(Fischer 2013.)


  • To create a uniform interface between components
  • Decouple implementations from the underlying services


Uniform Interface

Individual Resources are identified using URIs

Uniform Interface

Resources are abstracted from the data source and can be manipulated before being sent to a client

Uniform Interface

Hypermedia As The Engine Of Application State (HATEOAS)


    Self-contained and independent requests
  • Improves scalability
  • Allows for parallel processing of requests
  • Lets resources be viewed in isolation


    Decoupled clients and servers
  • Increases portability
  • Easier to scale

Layered System

    Endpoints can be the terminus or an intermediary service
  • Allows for load balancing and intermediate security enforcers

Why choose REST?

  • Easy to implement
  • Usable across many different platforms and languages

Why REST and Grails?

  • Many helpful defaults
  • Ease of development
  • Shorter development time

Getting Started

New in Grails 3

  • Based on Spring Boot
  • Switched to Gradle for build system
  • Major structural changes
    • Configuration
    • Scripts


De-coupled server and client means:

Getting Started

Resource Transformation


class Gr8Lady {
  String first
  String last

Getting Started

URL mappings




"/gr8ladies"(resources:"gr8lady") {
  "/chapters"(controller:"chapter", method:"GET")
--> /gr8ladies/{id}/chapters

Getting Started

Controller Responses

class CompanyController {
  def index() {
    respond company

uses either the accept header or file extension

10 Ways To Improve A RESTful API

with Grails Examples

1. Use Appropriate HTTP Status Codes

HTTP Status Codes

Learn the correct status codes for different errors

Code Description
2XX Successful
200 OK
4XX Client Error
400 Bad Request
403 Forbidden
404 Not Found
5XX Server Errors
500 Internal Server Error
502 Bad Gateway
an exerpt from


HTTP Status Pets & Fosters

Based on HTTP Status Dogs and HTTP Status Cats





Do's and Dont's

  • 200 is ok ... but not for everything
  • DON'T expect the end user to parse through the message for an error
  • DO Use an appropriate HTTP Error Response

HTTP Status Codes in Grails

Many of the cases are handled by Grails or the server(i.e. 5XXs)

HTTP Status Codes in Grails

if(someCondition) {
  render status: 4XX

2. Use the right HTTP verbs

  • GET to retrieve a resource
  • POST to create a new resource
  • PUT to update an existing resource
  • DELETE to remove an existing resource

HTTP verbs in Grails

Resource Annotation

Handled by Default! :)

HTTP verbs in Grails

On each Controller

class Gr8LadyController {
  static allowedMethods = [list: "GET", save: "POST", update: "PUT"]

HTTP verbs in Grails

URL Mappings

"/gr8ladies"(resource: "gr8lady", method: "GET")

3. Name Endpoints Consistently and Appropriately




  • NOT
  • NOT{id}/?action=delete
  • NOT

4. Style Consistently





Consistent URI style

Try Either:




And stick to it. Don't Mix and Match!

Consistent Style

Resource Names

plural nouns preferred


5. Provide Search Functionality
  • Lookup based on values

6. Support Multiple Media Types (JSON, XML)

  • XML and JSON are most common

Multiple Media Types (JSON, XML) in Grails

  • XML by default
  • By Parameter

Multiple Media Types (JSON, XML) in Grails

Available formats

    json: ['application/json', 'text/json'],
    xml: ['text/xml', 'application/xml']

Multiple Media Types (JSON, XML) in Grails

By Resource


@Resource(uri='/gr8ladies', formats=['json'])
class Gr8Lady {

Requesting another type returns a 406 (Not Acceptable)

Multiple Media Types (JSON, XML) in Grails

By RestfulController

class Gr8LadyController extends RestfulController {
  static responseFormats = ['json', 'xml']

Remember to add any response formats for versioned mime types

7. Provide Custom Response Formats

  • Filter from default responses
  • Provide different responses per version
  • Provide response formats based on security

Custom Response Formats in Grails

Object Marshallers


import grails.converters.JSON

class Bootstrap {
  def init = { servletContext ->
    JSON.registerObjectMarshaller(Gr8Lady) {
      def returnArray = [:]
      returnArray['firstName'] = it.first
      returnArray['lastName'] = it.last
      returnArray['chapter'] = it.chapter?.name
      return returnArray


render gr8lady as JSON

Custom Response Formats in Grails

Object Marshallers


import grails.converters.JSON
import org.gr8ladies.ChapterMarshaller

beans = {
    JSON.registerObjectMarshaller(new ChapterMarshaller())

Custom Response Formats in Grails

Object Marshallers

class Gr8LadyMarshaller implements ObjectMarshaller<JSON>{
    public boolean supports(Object object) {
      return object instanceof Gr8Lady
    public void marshalObject(Object object, XML converter) {
      Gr8Lady gr8lady  = (Gr8Lady)object
      converter.chars gr8lady.displayName

8. Use Hypermedia As The Engine Of Application State (HATEOAS)*

link to the resource and navigation

  "_links": {
    "self": { "href": "/gr8ladies" },
    "next": [
      { "href": "/gr8ladies?page=2" }

HATEOAS in Grails

  • JSON
  • Hypertext Application Language (HAL)
  • grails-app/conf/spring/resources.groovy

    beans = {
        halGr8LadyRenderer(HalJsonRenderer, org.gr8ladies.Gr8Lady)

HATEOAS in Grails

Usage: Content Negotiation

curl -i -H "Accept: application/hal+json" http://localhost:8080/gr8ladies/1

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: application/hal+json;charset=ISO-8859-1

  "_links": {
    "self": {
      "href": "http://localhost:8080/gr8ladies/1",
      "hreflang": "en",
      "type": "application/hal+json"
  "name": "Jenn Strater"

9. Or Use Pagination*


def list() {
  List gr8ladies = Gr8Lady.list(max: params.max, offset: params.offset)
  respond [results: gr8ladies, max: params.max, offset: params.offset]

10. And Versioning*

  • URI{id}
  • Custom Header
  • GET
    version: 2.0
  • Content Type
  • GET
    Accept: application/vnd.example.v2+json

Versioning in Grails

    • @Resource(uri='/gr8ladies/v1')
    • @Resource(uri='/gr8ladies/v2')
      Accept Header
    • "/gr8ladies"(version:'1.0', resources:"gr8lady", namespace: 'v1')
    • "/gr8ladies"(version:'2.0', resources:"gr8lady", namespace: 'v2')

Read-only Mode

  • for public APIs
  • or as a security measure

Read-only Mode in Grails

@Resource(uri="/gr8ladies", readOnly=true)
class Gr8Lady {
  String first


Related Plugins for other Grails versions

Spring Security REST Plugin

Token based Authentication based on Spring-Security

Last Updated May 2015

Source & Documentation

Greach 2014


Restful API Plugin

For more complicated APIs

Last Updated November 2014

Source & Documentation

Rest Renderer

For greater control over data output

Last Updated February 2014

Source & Documentation


  • REST is an architecture style, not a standard
  • There are many ways to implement REST
  • Grails makes implementing REST easy!
  • Don't reinvent the wheel, use standard practices.