Feature Request: Embedded DQL in GQL

I want to implement the following custom fields based on dql query:

type User {
    id: String! @id
    name: String! @search(by: [hash,term])
    followings: [User] 
    followers: [User] @hasInverse(field: followings)

   # Check if I follow the user
    is_following: Boolean @custom(dql: """
        query($logged_user_id: string!){
            queryIsFollowing(func: type(User)) {
			    cnt as count(followers @filter(uid($logged_user_id)))
                is_following: math(cnt == 1)
		    }
        }
    """)

    # The number of followings
    followings_count: Int @custom(dql: """
        query{
            queryFollowingsCounts(func: type(User)) {
			    followings_count: count(User.followings)
		    }
        }
    """)

    # The number of followers
    followers_count: Int @custom(dql: """
        query{
            queryFollowersCounts(func: type(User)) {
			    followers_count: count(User.followers)
		    }
        }
    """)

    created_at: DateTime!
   ...
}

But this feature is not yet supported, I hope team can provide support.

1 Like

I changed the title to something that makes more sense.

Ok, look forward to it soon.

I am wondering if this could be done now with a custom field dql that calls a custom query which calls custom DQL instead of custom http. I would think custom fields would support custom dql, but there are no examples in the docs…

type User {
  username
  followings_count: Int @custom(http: {
    url:  "https://YOUR DGRAPH ENDPOINT/graphql",
    method: GET,
    graphql: "query { getFollingCount(username) { ..."
  })
  ...
}

Type Query {
  getFollowingCount(username: String!): Int  @custom(dql: """
    ...custom DQL...
  )
}

Seems like a hack, a slow one, but I think this could work for now.

Again, I would think a custom field would support DQL and HTTP.

J

Here is a complete example with a custom DQL query inside of a GraphQL query…

https://dgraph.io/docs/graphql/custom/dql/

type Tweets {
	id: ID!
	text: String! @search(by: [fulltext])
	author: User
	timestamp: DateTime! @search
}
type User {
	screen_name: String! @id
	followers: Int @search
	tweets: [Tweets] @hasInverse(field: author)
}
type UserTweetCount @remote {
	screen_name: String
	tweetCount: Int
}

type Query {
  queryTweetsSortedByAuthorFollowers(search: String!): [Tweets] @custom(dql: """
	query q($search: string) {
		var(func: type(Tweets)) @filter(anyoftext(Tweets.text, $search)) {
			Tweets.author {
				followers as User.followers
			}
			authorFollowerCount as sum(val(followers))
		}
		queryTweetsSortedByAuthorFollowers(func: uid(authorFollowerCount), orderdesc: val(authorFollowerCount)) {
			id: uid
			text: Tweets.text
			author: Tweets.author {
			    screen_name: User.screen_name
			    followers: User.followers
			}
			timestamp: Tweets.timestamp
		}
	}
	""")

  queryUserTweetCounts: [UserTweetCount] @custom(dql: """
	query {
		queryUserTweetCounts(func: type(User)) {
			screen_name: User.screen_name
			tweetCount: count(User.tweets)
		}
	}
	""")
}

Your example is still a Custom Query, not a Custom Field.

What I am wondering is if you could run a custom dql query inside a custom field. It looks like custom fields only support http and not dql.

So, my hack is to run a custom field http that calls the custom query.

So, in your example, you would have:

type User {
  screen_name: String! @id
  followers: Int @search
  tweet_count: Int @custom(http: {
    url:  "https://YOUR DGRAPH ENDPOINT/graphql",
    method: GET,
    graphql: "query { queryUserTweetCounts(User) { ..."
  })
  ...
}

Which would indirectly call you queryUserTweetCounts custom query from a custom field. Obviously this would require a whole server jump that is unnecessary, but it does make it possible.

J

oh, you are right…

resolving updateGQLSchema failed because input:5: Type MyType; Field myField: @custom directive with dql can be used only on queries.

Not sure if there needs to be a real feature request for this… another one of those things we wouldn’t have to worry about if we had a pre-hook…

J