I'm writing a Grail REST Service and I've defined custom JSON converters. For instance, I have an event class which is converted like so whenever such an object is requested by a client...
// in src/groovy/EventMarshaller.groovy
class EventMarshaller {
void register(Object config) {
config.registerObjectMarshaller(Event) { Event e ->
return [
id: e.id,
title: e.title,
description: e.description,
dateCreated: e.dateCreated.format('yyyy-MM-dd'),
creator: e.creator
]
}
}
I register the EventMarshaller within a CustomObjectMarshaller which expects a named config parameter so that different REST API versions can be accommodated...
// in src/groovy/CustomObjectMarshallers.groovy
def register(String str) {
JSON.createNamedConfig(str) { cfg ->
marshallers.each {
it.register(cfg);
}
}
}
// in BootStrap.groovy init section...
def springContext = WebApplicationContextUtils.getWebApplicationContext( servletContext );
springContext.getBean("customObjectMarshallers").register("v1");
This works like a charm whenever I call to GET an event object via the REST API, the domain object is converted to the specified JSON format. For example, my event controller has an index action...
def index(String v)
{
def configName = 'v' + (v ?: 1)
def listOfEvents = Event.list()
// why does this only work when converting domain object to json?
JSON.use(configName) {
respond listOfEvents
}
}
Now I need update and save actions when PUT and POST commands are received from a client. So far I have the following in my update action...
def update(Long id, String v)
{
def configName = 'v' + (v ?: 1)
// how do I specify the version? JSON.use(configName) doesn't seem to work?
def jsonobj = JSON.parse(request);
def newEvent = new Event(jsonobj);
def evRequest = new EventRequest(jsonobj)
evRequest.errors.allErrors.each {
println it
}
...
Can anyone explain how I can tell the update action which config to use when converting the JSON to a domain object? (I've not seen any example of this online at all.) Also, the dateCreated field in the newEvent object is null after the JSON is parsed. How can I ensure that if a dateCreated field is present that it will be parsed into it's original date object?
Here's the command object referenced in the code...
/**------------------------------------------------------------
// EVENT REQUEST COMMAND OBJECT
//----------------------------------------------------------**/
class EventRequest
{
String id;
String title;
String description;
byte[] photo;
@BindingFormat('yyyy-MM-dd')
Date dateCreated;
//------------------------------------------------------------
// IMPORT CONTRAINTS FROM EVENT DOMAIN MODEL
//------------------------------------------------------------
static constraints = {
importFrom Event;
}
}
And the event domain class that it maps onto...
import java.util.Date;
import org.emvigr.user.*
import org.grails.databinding.BindingFormat;
class Event {
String title
String description
byte[] photo
@BindingFormat('yyyy-MM-dd')
Date dateCreated
// we can call user.addToEvents
static belongsTo = [
creator : User
]
static hasMany = [
portals : Portal
]
static constraints = {
title maxSize: 50
description nullable: true, maxSize: 300
photo nullable: true, maxSize: 2 * 1024 * 1024
dateCreated nullable: true
portals nullable: true
}
// when Events are accessed sort by the dateCreated (descending)
static mapping = {
sort dateCreated:"desc"
}
}
Any help much appreciated!