Exclude Properties from RESTful Responses and Improve the RESTService API (Part 2)

In my previous blog Create a REST API with Grails 2.3.x in 15 Minutes a basic REST service was created. Here I show how to customize and improve the REST API.

Exclude Properties from RESTful Responses

As you have noticed in my previous blog, the REST API delivers the data from the database without any restrictions.
In practice, there are many situations when such a behavior is not suitable or meaningful.
As an example, the class property is contained in the JSON response, but almost useless for the end user.

{
  "class":"com.jolorenz.rest.City",
  "id":1,
  "cityName":"Munich",
  "countryCode":"DE",
  "dateCreated":"2014-02-28T04:24:13Z",
  "lastUpdated":"2014-02-28T04:24:13Z",
  "postalCode":"81927"
}

In practice it is also desired to have a greater control about the response sent from the REST API.
Here I show how to exclude properties (e.g. class property and dateCreated) from the REST response, so we would end up with this response from the REST API:

{
  "id":1,
  "cityName":"Munich",
  "countryCode":"DE",
  "lastUpdated":"2014-02-28T04:24:13Z",
  "postalCode":"81927"
}

How to include or exclude properties from a rendered response, is described in the Grails docs and again super easy.
I will follow mostly the docs and the only things I have to do so far is to modify /conf/spring/resources.groovy:

// Place your Spring DSL code here
import grails.rest.render.xml.*
import grails.rest.render.json.JsonRenderer
import com.jolorenz.rest.City

beans = {
	cityXmlRenderer(XmlRenderer, City) {
		excludes = ['class', 'dateCreated']
	}
	cityJSONRenderer(JsonRenderer, City) {
		excludes = ['class', 'dateCreated']
	}
}

If you wonder how to name the beans, this is totally up to you and their names are not important. Grails will scan the application context for all available beans. So just make sure the name is somehow meaningful.

Fire up the Grails RESTService API from part 1 and check the API with curl:

curl -X GET -H "Accept:application/json" http://localhost:8080/RESTService/api/city/1

and the response is as:

{
  "id":1,
  "cityName":"Munich",
  "countryCode":"DE",
  "lastUpdated":"2014-02-28T04:24:13Z",
  "postalCode":"81927"
}

So far so good, but wait!
If I do the curl request without the id=1

curl -X GET -H "Accept:application/json" http://localhost:8080/RESTService/api/city

then the response still contains the class and dateCreated properties. So what to do?

There is only a brief information in the docs, that “Grails maintains a registry of grails.rest.render.Renderer instances”.
Looking at the repo grails.rest.render there is a JSONCollectionRenderer available.
With this information, we change /conf/spring/resources.groovy to:

// Place your Spring DSL code here
import grails.rest.render.xml.*
import grails.rest.render.json.*
import com.jolorenz.rest.City

beans = {
	cityXmlRenderer(XmlRenderer, City) {
		excludes = ['class', 'dateCreated']
	}
	cityJSONRenderer(JsonRenderer, City) {
		excludes = ['class', 'dateCreated']
	}
	cityXmlCollectionRenderer(XmlCollectionRenderer, City) {
		excludes = ['class', 'dateCreated']
	}
	cityJSONCollectionRenderer(JsonCollectionRenderer, City) {
		excludes = ['class', 'dateCreated']
	}
}

Obviously 2 beans have to be defined: one for collection rendering and another for single object!
Recheck with curl:

curl -X GET -H "Accept:application/json" http://localhost:8080/RESTService/api/city

and we receive the desired response also for the collection of objects:

[
 {
   "id":1,
   "cityName":"Munich",
   "countryCode":"DE",
   "lastUpdated":"2014-02-28T09:04:10Z",
   "postalCode":"81927"},
 {
   "id":2,
   "cityName":"Berlin",
   "countryCode":"DE",
   "lastUpdated":"2014-02-28T09:04:10Z",
   "postalCode":"10115"
 }
]

Pretty cool and super easy!

Summary

Here I showed how the response of the REST API was customized by excluding some database fields, so they don’t show up as a property.

HTH Johannes

Advertisements
This entry was posted in Development, Grails and tagged , , . Bookmark the permalink.

9 Responses to Exclude Properties from RESTful Responses and Improve the RESTService API (Part 2)

  1. Pingback: Create a RESTService API with Grails 2.3.x in 15 Minutes | Coding Snippets

  2. Pingback: Customize Properties from RESTful Responses and Improve the RESTService API (Part 3) | Coding Snippets

  3. Pingback: Logging HTTP Requests for better Debugging of the REST API (Part 4) | Coding Snippets

  4. Max says:

    Many thanks, very good example for understanding REST with Groovy.

  5. Rafael B.C. says:

    Im using grails 2.4.3 and it seems not working.

  6. Linh says:

    Nice post. Thanks.
    Is there a way to register default behaviour for all class types? Imagine if I have 20 domain classes, would I need to have 4 declarations for each domain class?

  7. olikaf says:

    just found this post, really helpful 🙂

  8. Muhamed Hakkim says:

    it is a very very helpful to me please put some extra examples it may helpful for beginners

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s