Send dgraph query response as JSON instead of Protocol Buffer

@akhiltak - After executing dgraph query, it return response with *graph.response type. It should return string so that I can convert it into valid JSON.

So @Rahul-Sagore it would still return response as graph.Response. The properties of the node can have a string value if there is a schema defined. That is what I was referring to. @akhiltak can help you with a schema file for Gru after which you would get the correct types in the response.

Okay, thanks. My Bad.

This is the response I was getting in postman:

{
  "n": {
    "uid": 3386310919693814617,
    "attribute": "root",
    "properties": [
      {
        "prop": "name",
        "val": "QWxnb3JpdGhtIDI="
      },
      {
        "prop": "_uid_"
      }
    ]
  },
}

Which is in a bit wierd format. I thought the format will get fixed and will come as:

{
  "root": {
    "uid": 3386310919693814617,
    "name": "Algorithm"
  }
}

As per the wiki. It is easier to use.

Hmm, so the format at the bottom that you are referring to is the format that the HTTP Server responds in which is JSON.

The above format is the one in which the gRPC server responds(to which the Go Client talks to). Sorry for the confusion, its inevitable as all examples on Wiki are for the HTTP Client. Regarding the val being base64 encoded, I think that can be taken care of if we have a schema. Could you tell me how do you convert the response from the server to JSON?

If you need JSON, then you could just directly use the /query interface, instead of using the Go client. It responds back in a much more friendly JSON than what you’d get by converting protobuf to JSON.

Also, don’t block on schema. It’s a work in progress, and it’s only going to give you what you can already custom write.

2 Likes

@pawan I hoped that the response will come as second json example, but it was like the first one.

This the code to fetch the tag name with UID and then converting it to json:

 q := "{root(_uid_: 11905117936582384613 ) { name _uid_ }}"
resp, err := c.Query(context.Background(), &graph.Request{Query: q})

jsonResp, err := json.Marshal(resp)

w.Header().Set("Content-Type", "application/json")
w.Write(jsonResp) //Writing json response to postman request

Above code outputs :

{
  "n": {
    "uid": 3386310919693814617,
    "attribute": "root",
    "properties": [
      {
        "prop": "name",
        "val": "QWxnb3JpdGhtIDI="
      },
      {
        "prop": "_uid_"
      }
    ]
  },
}

All the tag properties I asked is coming in array of object, with prop and val keys. Now if I have to get the tag name, I have to loop through the array and see check if prop == “name” (On UI side), which is a lot more calculation if have more properties.

@mrjn - I’ll try by hitting /query

Yup try the /query endpoint and use that if it works better for you.

1 Like

I have changed the code to fetch data from /query endpoint. I got this result in postman:

"{\"root\":{\"_uid_\":\"0x6cc3f59d7dec1ed6\",\"name\":\"Algorithm 2\"}}"

This doesn’t look good in postman due to escaping double qoute by slash. But this the perfect format for response, which I wanted. I can parse it on Frontend to use it, thanks.

Just make sure, the uid has correct format, I am fetching data with UID something like “9025164383225914740”, but in above response it is different.

2 Likes

That’s great. Actually, you can just use the base 16 encoded uid(0x6cc3f59d7dec1ed6) that you get in the response.

The Go Client was returning it in the internal format(uint64) which should be changed.

2 Likes

Hi @Rahul-Sagore,

If you are using the /query endpoint, you could use a schema file as an input while running the server to get appropriate types like this:

  1. Create a schema file.
  2. Run dgraph server with addition argument:
  • ./dgraph … -schema < schema-filepath >

Schema file(*.json):

{
	"_uid_": "id",
	"name": "string",
	"age": "int"
}

Where the key-value pair represents predicate and it’s type respectively.

This would return a response like this:

        "root": {
          "_uid_": "0x6cc3f59d7dec1ed6",
          "age": 23,
          "name": "Rahul",
          "human": true
        }

Note that:

  • This will still be a json encoded string, so you will have to decode it at frontend
  • ID has type string, as per GraphQL spec
  • Currently only scalar types are supported
  • No type coercion is currently being done in mutations, so you could potentially store wrong types (but this validation will be merged soon)
  • Scalar types you could use are: id, string, int, float and bool

Please do let me know if you have any doubts regarding this.

PS: Apologies for the tardy response.
PPS: Will be adding this to wiki as soon as type validation is added to mutations.

4 Likes

do you mean the “http://server:port/query?” interface? if so, which means we need to use http instead of grpc in TCP, right?

Or do you have a query interface through grpc?

Thats right @Rader.

To get the response back as JSON you have to use http://server:port/query interface. gRPC using the Go client would return result as Protocol Buffers.