We plan to add support for GraphQL± queries in GraphQL. This doc talks about how that would look, what are some of the design decisions and things that would be and would not be supported in the first version.
Implementation
We would support these as custom queries. We already have the @custom
directive, another field called dql
would be added to it.
For the schema below
type Tweets {
id: String! @id
text: String! @search(by: [fulltext])
user: User
timestamp: DateTime! @search
score: Int @search
streams: String @search
}
type User {
screen_name: String! @id
tweets: [Tweets] @hasInverse(field: user)
followers: Int @search
}
type Query {
myCustomTweetQuery(searchTerm: String!): [User] @custom({ dql: """
query ($searchTerm: string) {
var(func: type(Tweets)) @filter(anyoftext(Tweets.text, $searchTerm)) {
Tweets.user {
f as User.followers
}
}
myCustomTweetQuery(func: uid(f), orderdesc: val(f)) {
screen_name
User.tweets(first: 5) {
text
score
}
}
}"""})
}
Note - The underlying GraphQL± query should have a named query with the same name as your GraphQL custom query i.e. myCustomTweetQuery
in this case. We’ll only look for that key in the response.
The above query would filter tweets having GraphQL
in them, get the authors for them and store them in a variable. The next named query would get the top authors and their first 5 tweets. Something like this isn’t possible right now. The way this would work is that we call the underlying GraphQL± query and then apply the GraphQL completion logic (ensure non-null fields are present etc.) on the result that we get. We can similarly have aggregation queries working.
There are certain caveats with this:
-
Auth - Auth rules won’t work directly with this since you are bypassing the GraphQL part by executing a GraphQL± query. To make this work properly, we would need to parse the GraphQL± query and apply the auth rules there before sending it to Dgraph. This would require some work to get working properly and for now, such queries should error out.
-
The data requested by the user would be limited by what they have asked in the underlying GraphQL± query. So if the ± query didn’t fetch the followers for a user but the GraphQL query asked for it, we won’t be able to return them. We could be smarter about this in a later iteration and write the bits that are asked by the user into the GraphQL± query.
Example
GraphQL query
queryTweets {
text
score
user {
name
}
}
but if the underlying GraphQL± query just returned the tweet text and score, then we just return that. We don’t rewrite the ± query based on the GraphQL query for now.
- Arguments won’t be allowed in the GraphQL query - Filters, pagination and ordering applied in the GraphQL query won’t directly be translated to the underlying query. Say you did a GraphQL query like
queryTweets {
user(filter: {...}) {
followers(first: 5) {
...
}
}
}
To apply the filter and other arguments properly we would again have the parse the underlying GraphQL± query and modify it to translate all of this to it. In the first version, we could avoid such queries and return an error for them.