I’ll give this a go!
The Geo features appear to be supported by the JSON API:
https://dgraph.io/docs/mutations/#geolocation-support
I’ll give this a go!
The Geo features appear to be supported by the JSON API:
https://dgraph.io/docs/mutations/#geolocation-support
Yes, I too just discovered this:
The /query
endpoint accepts two content types:
For application/json
, it accepts the following JSON object:
{
"query": "some graphql+- query",
"variables": map[string]string
}
But, I am not sure how to send variables in that query so that it could be directly plugged into @custom
.
We will think about this.
I think the only issue would be the query. Need to check if mutations need to be via HTTP API. I think it would run normally in GraphQL mutations.
Just want to jump in here and say that this support/level of discussion is incredible, guys.
That variable field is called “GraphQL var”. It is ours, it is not related to GraphQL. See Query Language - Query language
That’s great! So, graphql± has variables too. Its amazing.
But it still won’t be pluggable directly to @custom
for queries with variables, as the query
field inside the JSON object is a string (a primitive value). We don’t replace @custom
variables inside a primitive value. Instead, we assume that the variable itself is a whole primitive value, and not part of a primitive value.
Yes, looking at the code, it is impossible in the current format whereby it considers the entire string starting with $ as the key.
I’d say you could change it so that it splits the strings by whitespace and then considers each of the resultant strings in the slice by whether or not they begin with the $
symbol, rather than the entire string, then reconstructs the string (but that feels like reinventing fmt.Sprintf).
Yeah!
So, if you had a JSON like:
{
"k1": $v1,
"k2": "$v2"
}
Then we can’t really replace $v2
with the variable value, as then there would be no way of distinguishing a simple json string and a variable.
We only replace $v1. Variables are supposed to be present without quotes, otherwise we can’t distinguish a string from a variable. Someone may actually be wanting to just send “$v2” as the value.
So, you will need to write a separate backend app to do the part of forming the graphql± query, and use that with @custom
.
Ok, I might wait for @michaelcompton to respond about the planned timelines for the inclusion of GraphQL± natively in the @custom
directive before I proceed to write any middleware.
And I remember, @vardhanapoorv had tried this thing through Apollo federation (apollo acts as the middleware in this case). He can clarify more on this.
@abhimanyusinghgaur not sure if I got it.
e.g
type Query{
getGeo(name: String!, v1: String!, v2: String!): GeoObject @custom(http:{
url: "https://localhost:8080/query"
method: "POST",
body: "{ "query": "{ q(func: eq(name, \"$name\")) { uid name } }, "variables": {"$a": $v1, "$b": $v2, "$name": $name }"}"
})
}
Do you mean that we can’t pass the GraphQL variable to Dgraph’s GraphQL variable?
Feels like we don’t even would need to use it. Maybe it could be straightforward.
e.g:
type Query{
getGeo(name: String!): GeoObject @custom(http:{
url: "https://localhost:8080/query"
method: "POST",
body: "{ "query": "{ q(func: eq(name, $name)) { uid name } } "}"
})
}
That wouldn’t work?
Also, I don’t see many users using GraphQL Variables in Dgraph context - not sure if it is useful right now. It is used in GraphQL more tho.
Actually, yeah! this is possible. This way we can use it directly with @custom
! As, the GraphQL variables will be replaced inside the “variables” in JSON. It’s cool!
We will need to modify the query slightly like:
type Query{
getGeo(name: String!, v1: String!, v2: String!): GeoObject @custom(http:{
url: "https://localhost:8080/query"
method: "POST",
body: "{ query: \"query q($name: string) { q(func: eq(name, $name)) { uid name } }\", variables: {$a: $v1, $b: $v2, $name: $name }}"
})
}
Earlier, I was thinking about only replacing variables directly in “query”, but that wouldn’t have been possible as the “query” value is string which contains the actual query, and we don’t parse variables from inside a string. But with this variable approach, it is possible to directly call dgraph.
Yes, this is what I was saying wouldn’t work as the variable can’t be replaced if it is present inside a string. But, in the other approach, it will work because GraphQL can identify the variables in that case and replace them with their value. Then, dgraph will receive the correct JSON and it will all work!
No middlewares required now!
Thanks @MichelDiz.
Thanks to both of you! I will attempt to setup the Geo stuff tonight and come back to you with my success
At the moment, support for scalars inside body is not there in master. So, directly specifying the query string inside body won’t work for now. We will be adding support for scalars soon. In the meantime, you will need to send even the query as a variable like:
type Query{
getGeo(name: String!, query: String!): GeoObject @custom(http:{
url: "https://localhost:8080/query"
method: "POST",
body: "{ query: $query, variables: {$name: $name}}"
})
}
Where the value of $query will be: “query q($name: string) { q(func: eq(name, $name)) { uid name } }”
Update: @machship-mm We have decided to work on adding Geo types in GraphQL too. Hope to have it out soon.
Amazing!! Thanks guys.
Also, apologies for not having come back to you as yet… I’ve had no time to try it out yet
Hey @machship-mm,
Here is the RFC for implementing Geo types in GraphQL: Implementing Geo features in GraphQL
We would love your feedback on it! Would be real nice to see if it satifies your use-case.
Hey @machship-mm I have found the solution with @vardhanapoorv. We have to forward the headers to make it work. I have tested the query bellow:
type Test @remote {
data: Q
}
type Q @remote {
q: [TestR]
}
type TestR @remote {
test: String
}
type Query {
getCountry(query: String!): Test
@custom(
http: {
url: "http://localhost:8080/query"
forwardHeaders:["Content-Type"]
method: "POST"
body: "{ query: $query }"
})
}
That approach can be unsafe in some levels, so you should combine with @auth
directive.
query {
getCountry(query: "{ q(func: has(test)) { test } }") {
data { q { test } }
}
}
@michaelcompton @pawan @abhimanyusinghgaur
I know that we gonna support Geo queries, but this approach is good for any kind of special query.
Note: Now that we know that this type of query is possible. It would be interesting to be able to do the body in a more dynamic way. The parser prevents us from using static queries. And let only the values to be dynamic.
Thanks @MichelDiz.
Yeah! we don’t support scalars in custom query body ATM. I will pick it up in the next sprint, so we can have static graphql± queries in the body.
Do we have a ticket? (Jira?) I wanna add some things on it.
Yup! let me ping you on slack.