Forum Discussion

shawn-ad's avatar
12 years ago

Get JSON from internal rest() call

I'm making some REST calls within a custom component. Rather that traverse a nested response object in FreeMarker, I'd prefer to receive a JSON string, which I could insert as a data-* attribute on one of the HTML nodes in my custom component and deal with on the client-side using JavaScript. So I'd like to do something like this:

<div class="hidden my-data" data-board-topics="${
rest("/boards/id/extensions/topiclist?restapi.format_detail=full_list_element&restapi.response_format=json")
}">

However, when I append "&restapi.response_format=json" to the rest parameter, it still returns a nested response object, not a JSON string. I know I can get JSON by making an external REST API call from the client side, but is there a way to get a JSON string from the internal rest function?

8 Replies

  • shawn-ad's avatar
    shawn-ad
    Guide
    12 years ago

    Thank you. I'll have to try it to be sure, but I don't see where this macro inserts quotes around strings in the resulting JSON, and I don't see any escaping happening, so I don't think the JSON would be safe to use in JavaScript code if the data was tainted and unescaped.

     

    Lithium Engineering: Please add a native options for escaped JSON string output from the internal rest() function.

  • YuriK's avatar
    YuriK
    Khoros Expert
    12 years ago

    Hey Shawn-ad,
    You can do the following (Thanks DougS) in an endpoint (but not in components):

     

    1) Create an endpoint with your rest call similar to the following (Note: the @@markup call will get you the xml string for the freemarker object):

     

    ${rest("/threads/recent").@@markup}

     

    2) Set return type to text/plain

     

    3) call your endpoint with the following query parameter

     

    ?xslt=json.xsl

     

    This should return the json as a string.

     

    Hope this helps,

     

    Yuri

     

  • shawn-ad's avatar
    shawn-ad
    Guide
    12 years ago

    Thanks, Yuri. It is interesting that I can use your suggestion to convert any XML emdpoint into JSON. However, I was trying to get JSON data rendered inside the page HTML so that I don't have to make a separate HTTP request to the API (or to a custom endpoint).

     

    Clearly Lithium has a way to get an API response as XML markup (using @@markup an endpoint). it would be great if I could get JSON using a similar FreeMarker translation method, and do so in a component to get it rendered in-page.

  • luk's avatar
    luk
    Boss
    10 years ago
    big +1000, the problem is not to get JSON from an endpoint but inside a component or any type of freemarker code...the rest() lithium context object ALWAYS returns a freemarker node when used in a freemarker template, this makes things much harder as they would need to be =/
  • DougS's avatar
    DougS
    Khoros Oracle
    10 years ago

    We will be releasing a couple Freemarker context objects for 14.12 that should help with these types of things.  For REST V2, we are releasing a new object named apiv2 that will have two functions in it: apiv2.toJson(<your v2 freemarker object>) and apiv2.toxml(<your v2 freemar object>).   You'll be able to take a REST V2 response, navigate its object graph, and then print out the object as a JSON or XML string (kind of similar to .@@markup for REST V1).  An example:

     

    <#assign liql = "SELECT * FROM messages WHERE board.id = 'studio'" />
    <#assign resp = rest("2.0", liql?url) />
    <#-- print out the first item in the list of messages -->
    ${apiv2.toJson(resp.data.items[0])}

     

     

    We'll also be releasing an object named restd that we already had (just for API V1 XML responses), but that was previously un-documented, and that has been extended to work with JSON for API V1 and V2.  The restd object will make a REST API call, but instead of returning a wrapped object response it will return either an XML string or a JSON string, depending on how the call is made.

     

    • ${restd("/boards/id/extensions/topiclist")} will return an XML string version of an API V1 response.  
    • ${restd("/boards/id/extensions/topiclist", "json")} will return a JSON string version of an API V1 response.
    • ${restd("2.0", "/search?q=SELECT+*+FROM+messages")} will return a JSON string version of an API V2 response.
    • ${restd("2.0", "/search?q=SELECT+*+FROM+messages", "xml")} will return an XML string version of an API V2 response.

     

    -Doug

  • luk's avatar
    luk
    Boss
    10 years ago
    Cool, thanks for the information Doug, sound amazing, is that undocumented restd() context object already available in 14.10?
  • DougS's avatar
    DougS
    Khoros Oracle
    10 years ago
    It's there, but it only works for XML (not JSON). 14.12+ for JSON unfortunately