Rendering a Map to a Grails GSON View
So, I am writing to write a Grails application when I discovered this new way to present JSON objects - using Grails GSON Views!
I haven't used Grails since version 2.x and now I jumped to version 5.1.1 – that's why GSON view is new to me!
GSON Basics
Basically, a GSON view works like a GSP view but we will write code using a JSON-like DSL instead of something HTML-like.
For example we have this controller:
class UserController {
def show(Long id) {
respond new User(
id: 1,
firstName: 'Johnny',
lastName: 'Appleseed',
emailAddress: 'johnny_apples@example.com'
)
}
}
Then we have the corresponding GSON file in grails-app/views/user/show.gson
:
model {
User user
}
json {
id user.id
fullName "${user.firstName} ${user.lastName}"
emailAddress user.emailAddress
}
With that, calling the endpoint will result a JSON that looks like the one in the GSON file.
{
"id": 1,
"fullName": "Johnny Appleseed",
"emailAddress": "johnny_apples@example.com"
}
Grails views has a great documentation here and it shows different ways to render different objects using GSON. The problem here is I can't find in the documentation on how to properly render a Map
. The goal here is to show the URL mappings of my Grails application dynamically.
All I can see in the documentation is how to render a List
, Set
, or any linear collections in GSON.
First, I tried call(Iterable, Closure)
method with the given Map
as the 1st parameter. This did not work or even compile since Map
is not an Iterable
, according to the docs.
Second, I tried using the .entrySet()
and .keySet()
methods of the Map
interface to make it fit with the Iterable
requirement.
This made the compilation errors disappear, but I still didn't get the JSON format I wanted to show. The Map
should be presented with key-value pairs from the values stored in it and not create a List
from a Map
!
Create a new Map
While thinking of a solution, I remembered how we do JSON marshalling back in Grails 2: create a Map
in the form of the JSON we want to present.
To do that, I used Groovy's collection manipulation methods such as .dropWhile()
, .groupBy()
, and especially .collectEntries()
– which creates a Map
from the size-2 (key, value) list that its closure returns. Now the GSON file looks like this:
With the GSON file above, I can now show the URL mapping data with the format that I want it to be!
{
"message": "Welcome to my API!",
"version": "0.1-dev",
"urlMappings": {
"/": {
"*": "index"
},
"/users": {
"GET": "showAll",
"POST": "save"
},
"/users/(*)": {
"GET": "show",
"PUT": "update",
"DELETE": "delete"
}
}
}
I hope this helps anyone that needs to render a Map to their Grails GSON view!