RejectedSoftware Forums

Sign up

REST API and returning JSON

I'm trying to use the REST API generator for a series of calls like this,

import vibe.d;

interface MyInterface {
  @property string emit_json();
}

class MyClass : MyInterface {
  @property string emit_json() {
    Json j = Json.emptyObject;
    j.foo = "123";
    j.bar = "456";
    j.quxx = "789";
    return j;
  }
}

shared static this() {
    ...
        auto router = new URLRouter;
        router.registerRestInterface(new MyClass);
    ...
}

but this fails to compile on implicit conversion:

source/app.d(14): Error: cannot implicitly convert expression (j) of type Json to string

I tried generating a string,

    string s = j.toString();
    return s;

but the return goes through another string conversion and gets escaped:

$ curl -v http://127.0.0.1:8080/emit_json
* Hostname was NOT found in DNS cache
*   Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
> GET /emit_json HTTP/1.1
> User-Agent: curl/7.37.1
> Host: 127.0.0.1:8080
> Accept: */*
>
< HTTP/1.1 200 OK
* Server vibe.d/0.7.20 is not blacklisted
< Server: vibe.d/0.7.20
< Date: Sun, 31 Aug 2014 20:53:22 GMT
< Keep-Alive: timeout=10
< Content-Type: application/json; charset=UTF-8
< Transfer-Encoding: chunked
<
* Connection #0 to host 127.0.0.1 left intact
"{\"foo\":\"123\",\"bar\":\"456\",\"quxx\":\"789\"}"

What is the proper way to produce and return JSON via the REST API generator? Am I missing the intention/abusing the generator and should just create a HTTP route for each and set the response type?

Thanks.

Re: REST API and returning JSON

Outputting JSON is much easier than you think:

 class MyClass : MyInterface {
   Json emit_json() {
     Json j = Json.emptyObject;
     j.foo = "123";
     j.bar = "456";
     j.quxx = "789";
     return j;
   }
 }

I don't think there is any need to define the functions as properties either.

As for you last example, is it not returning valid JSON? It's simply being escaped because you are outputting the string to the screen and it's being escaped for display purposes. Json.toString() definitely outputs a JSON string that's ready for consumption by a parser.

Re: REST API and returning JSON

On Mon, 01 Sep 2014 03:29:02 GMT, David Monagle wrote:

Outputting JSON is much easier than you think:

 class MyClass : MyInterface {
   Json emit_json() {
 ...

I don't think there is any need to define the functions as properties either.

I think you highlighted the problem... I had string as the return type. Whoops. Also thanks for pointing out that I don't need property. I copied the example without understanding it.

As for you last example, is it not returning valid JSON? It's simply being escaped because you are outputting the string to the screen and it's being escaped for display purposes. Json.toString() definitely outputs a JSON string that's ready for consumption by a parser.

No, after the pass through string encoding (json->string->string), the escaping prevents it from being consumed properly in the browser and in a Ruby's json lib.

Re: REST API and returning JSON

This happens because the REST interface protocol serializes your return value to JSON. String serialized to JSON is always double quoted. And all double quotes in string are escaped.

Try in your Ruby client to deserialize two times:

my_object = JSON.parse(JSON.parse(rest_response))