How to respond with JSON directly from a rest call in Grails and bypass the renders

1,109 views
Skip to first unread message

Scott Ryan

unread,
Sep 26, 2014, 6:42:47 PM9/26/14
to grails-de...@googlegroups.com
I have a number of REST services that return JSON and the original source is JSON from a Mongo Data Store or it is generated dynamically.   It looks like the only way I can respond back from a Rest call using the Rest Controller is to convert the data from JSON or XML to a Map and let the default renderer render it.   Most of the time the source data is XML or JSON to begin with.   This has incurred huge over head.  Is there a way to:

1. Detect the incoming accept header value
2. Return the true response and bypass the Grails renderers.  That way I can generate either XML or JSON directly and not have to convert it to a MAP. 

I tried just returning the data directly but then it expects to render it as a GSP.  

Is the REST Support for Grails just intended to support CRUD operations or can it also support URL that just request business services?

Thanks

Scott Ryan

Dhiraj Mahapatro

unread,
Sep 26, 2014, 7:34:55 PM9/26/14
to grails-de...@googlegroups.com
This can be done in Grails (latest versions from 2.3). You can get a clear idea about it reading through docs related to respond() which is available to controllers by default.


Hope that helps.


--
You received this message because you are subscribed to the Google Groups "Grails Dev Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to grails-dev-disc...@googlegroups.com.
To post to this group, send email to grails-de...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/grails-dev-discuss/ffbb1f6d-36b4-4fc0-9991-31ba3a9d5174%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Dhiraj..

Scott Ryan

unread,
Sep 30, 2014, 5:07:13 PM9/30/14
to grails-de...@googlegroups.com
Not sure if you read my whole post but I am familiar with the documentation and have been using Grails for many years.  The issue is that out of the RestController there does not appear any way to return the payload directly.  If I use respond it tries to convert my data to JSON and assumes it is a map despite the signature being Object. If I use render of couse it tries to render a GSP. If I just return the data is again tries to render a GSP.   I need to be able to return pure JSON from the controller and to return a multi part response with a binarry attachment.  I know I can do this writing my own custom controller however wondering if anyone was able to do this with the default implementation of the RestController.   I have done this with a custom controller but would like to take advantage of the capability in the RestController but return pure JSON as that is what is coming from my Mongo DB and not have to convert it to a map to use the respond function.

Thanks
Scott Ryan

Scott Ryan
President/CTO
Soaring Eagle L.L.C.
Highlands Ranch, Co. 80130
(303) 263-3044
sc...@theryansplace.com
www.soaringeagleco.com

--
You received this message because you are subscribed to a topic in the Google Groups "Grails Dev Discuss" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/grails-dev-discuss/Tj3T9ugkkCQ/unsubscribe.
To unsubscribe from this group and all its topics, send an email to grails-dev-disc...@googlegroups.com.

To post to this group, send email to grails-de...@googlegroups.com.

Dhiraj Mahapatro

unread,
Sep 30, 2014, 7:37:17 PM9/30/14
to grails-de...@googlegroups.com
Can you provide a simple example (FooController) what you are trying to achieve?

Correct me if I am wrong. 
Are you looking for a simpler approach using RestfulController to produce a multipart HTTP response (a binary attachment (say PDF) ) with a  JSON response body?

Thanks
Dhiraj

On Tue, Sep 30, 2014 at 5:07 PM, Scott Ryan <sc...@theryansplace.com> wrote:
Not sure if you read my whole post but I am familiar with the documentation and have been using Grails for many years.  The issue is that out of the RestController there does not appear any way to return the payload directly.  If I use respond it tries to convert my data to JSON and assumes it is a map despite the signature being Object. If I use render of couse it tries to render a GSP. If I just return the data is again tries to render a GSP.   I need to be able to return pure JSON from the controller and to return a multi part response with a binarry attachment.  I know I can do this writing my own custom controller however wondering if anyone was able to do this with the default implementation of the RestController.   I have done this with a custom controller but would like to take advantage of the capability in the RestController but return pure JSON as that is what is coming from my Mongo DB and not have to convert it to a map to use the respond function.

Thanks
Scott Ryan

Scott Ryan
President/CTO
Soaring Eagle L.L.C.
Highlands Ranch, Co. 80130
(303) 263-3044
sc...@theryansplace.com
www.soaringeagleco.com

.

Jeff Scott Brown

unread,
Sep 30, 2014, 10:59:02 PM9/30/14
to grails-de...@googlegroups.com


On September 30, 2014 at 4:07:13 PM, Scott Ryan (sc...@theryansplace.com) wrote:
> Not sure if you read my whole post but I am familiar with the documentation
> and have been using Grails for many years. The issue is that out of the
> RestController there does not appear any way to return the payload
> directly. If I use respond it tries to convert my data to JSON and assumes
> it is a map despite the signature being Object. If I use render of couse it
> tries to render a GSP. If I just return the data is again tries to render a
> GSP. I need to be able to return pure JSON from the controller and to
> return a multi part response with a binarry attachment. I know I can do
> this writing my own custom controller however wondering if anyone was able
> to do this with the default implementation of the RestController. I have
> done this with a custom controller but would like to take advantage of the
> capability in the RestController but return pure JSON as that is what is
> coming from my Mongo DB and not have to convert it to a map to use the
> respond function.


I am not sure if this is the sort of thing you are looking for or not.  Does something like this help you?…

render(contentType: "application/json") {
    book(title: b.title, author: b.author)
}



JSB

--
Jeff Scott Brown
jbr...@pivotal.io

Find The Cause ~ Find The Cure
http://www.autismspeaks.org/

Scott Ryan

unread,
Sep 30, 2014, 11:30:49 PM9/30/14
to grails-de...@googlegroups.com
I will send more details tomorrow but I am looking for something that allows me to send JSON directly.  Like

index(){
def json = '{"name":"Joe","location":"Seattle"}'

respond json
}

but the respond always assumes that json is a map.    The JSON in this case come directly out of a Mongo Database and is returned to the user as JSON.


Scott Ryan

--
You received this message because you are subscribed to a topic in the Google Groups "Grails Dev Discuss" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/grails-dev-discuss/Tj3T9ugkkCQ/unsubscribe.
To unsubscribe from this group and all its topics, send an email to grails-dev-disc...@googlegroups.com.
To post to this group, send email to grails-de...@googlegroups.com.

Jeff Scott Brown

unread,
Sep 30, 2014, 11:39:00 PM9/30/14
to grails-de...@googlegroups.com


On September 30, 2014 at 10:30:49 PM, Scott Ryan (srya...@gmail.com) wrote:
> I will send more details tomorrow but I am looking for something that allows me to send
> JSON directly. Like
>
> index(){
> def json = '{"name":"Joe","location":"Seattle"}'
>
> respond json
> }
>
> but the respond always assumes that json is a map. The JSON in this case come directly out
> of a Mongo Database and is returned to the user as JSON.
>


You can do this…

render json

If json is a String, that will be rendered.

Scott Ryan

unread,
Oct 1, 2014, 10:16:55 AM10/1/14
to grails-de...@googlegroups.com
If I use your first example it fails trying to use the JSON builder to build JSON from my String. 

If I just render the string it sends the string back in the response however the content type is marked html/text and the cookies are not handled properly.   

I had hoped to use the new Rest capability from Grails as a drop in replacement for my Jersey Grails implementation but it looks like is is a great solution for normal CRUD based grails apps but is a little rough when trying to do deep processing with embedded Paths and non traditional return types.  I will continue to work with it and see if I can get my other use cases to work in the new framework.  It looks great and will continue to improve and is a great solution for a majority of our problems but not really for out more advanced requirements.

thanks for the quick and useful answers

Scott Ryan


--
You received this message because you are subscribed to a topic in the Google Groups "Grails Dev Discuss" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/grails-dev-discuss/Tj3T9ugkkCQ/unsubscribe.
To unsubscribe from this group and all its topics, send an email to grails-dev-disc...@googlegroups.com.
To post to this group, send email to grails-de...@googlegroups.com.

Gregory Dickson

unread,
Oct 1, 2014, 11:02:04 AM10/1/14
to grails-de...@googlegroups.com, sc...@theryansplace.com
Scott, you can write to the output stream and set the content type directly. I did this to return a binary image:

def viewImage (){

     def image_record = Image.get( params.id )
     byte[] an_image = image_record.image 
 response.contentType = 'image/png' 
 response.outputStream << an_image

Scott Ryan


To unsubscribe from this group and all its topics, send an email to grails-dev-discuss+unsub...@googlegroups.com.

To post to this group, send email to grails-de...@googlegroups.com.

Jeff Scott Brown

unread,
Oct 1, 2014, 11:05:01 AM10/1/14
to grails-de...@googlegroups.com


On October 1, 2014 at 9:16:55 AM, Scott Ryan (sc...@theryansplace.com) wrote:
> If I use your first example it fails trying to use the JSON builder to
> build JSON from my String.
>
> If I just render the string it sends the string back in the response
> however the content type is marked html/text and the cookies are not
> handled properly.

If you want to specify the content type you can…

render text: someStringThatContainsJSON, contentType: “application/json”

Dhiraj Mahapatro

unread,
Oct 1, 2014, 11:16:08 AM10/1/14
to grails-de...@googlegroups.com
You beat me to it, Jeff.

@Scott - You can also specify the status code in case you are handling an error json response

render text: errorjsonstring, contentType: 'application/json', status: 400

Sorry its thumb typed, google groups is blocked at my work place. this will be an immediate request right now to unblock.

Thanks
Dhiraj Mahapatro
> --
> You received this message because you are subscribed to the Google Groups "Grails Dev Discuss" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to grails-dev-disc...@googlegroups.com.
> To post to this group, send email to grails-de...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/grails-dev-discuss/etPan.542c181b.327b23c6.5b80%40JSB-MBP-August-2012.local.

Paco Zarate

unread,
Oct 1, 2014, 12:05:50 PM10/1/14
to grails-dev-dis.
Great tips!

Thank you guys, I will be using them on my project too, I have a similar use case.


Reply all
Reply to author
Forward
0 new messages