DQL is Dgraph's own query language. It has GraphQL like syntax but is more versatile than GraphQL. Take a tour of DQL and find it out for yourself.
In this post, we will get started using custom DQL queries with GraphQL in Slash GraphQL. We will continue the Todo Starter Application we built in a previous blog and add some more features to it.
Building a TodoList App
In a previous blog post on Build a React app with Slash GraphQL by Michael we built a Todo app that looked like this:
![](upload://9J381olTaeNJ6pwBLCTePXBWneI.png)
This time, I want to enhance it, by having todos inside a todo list and having a lot of such different lists. That way, I can keep my todos organized. I will keep all my personal todos in a personal list, learning goal todos in a learning list, office todos in an office list, and so on …
We won't be going over building the UI, but we will just build the backend we need for the UI.
So, I will need a TodoList
that will store the Todo
s. This todo list will need three bits of data:
- a unique identifier,
- a name for the list, and,
- a list of todos that belong to the list.
As a GraphQL type, that's this:
type TodoList {
id: ID!
name: String!
todos: [Todo!]
}
Now, I want the first screen in the UI to show me a summary view of all the todo lists.
In the summary screen, I want the todo lists to appear in a sorted order based on the number of incomplete todos they have. I also want the summary screen to show me the number of incomplete and total todos for each TodoList
. That will help me bring the list with the most incomplete todos at the top, so whenever I open my application, the first list I see will be the list that needs the most of my attention.
For this, I need a query in my Slash GraphQL backend that can give me the data needed for rendering the summary screen UI. We won't be able to achieve this with the auto-generated queryTodoList
query, because the order
argument in that query will only be able to order based on the fields directly present in the TodoList
type, it can't order based on some field in the todos inside the TodoList
.
Similarly, to get the counts of total and incomplete todos for each TodoList
, I will have to query unnecessary data and do some client-side processing, if I were to use the auto-generated queryTodoList
query. So, what if the backend could give us the results we want? That is exactly where custom DQL queries come into play.
DQL stands for Dgraph Query Language
(Dgraph is the database on top of which Slash GraphQL runs). DQL is a more feature-rich query language that supports variables in queries unlike GraphQL and is better suited for such ad-hoc scenarios which are not fulfilled by the auto-generated GraphQL CRUD API provided by the Slash backend. Custom DQL queries can be easily hooked into the Slash GraphQL backend. Let's see how.
First, let's add the following to our GraphQL schema:
type TodoListSummary @remote {
id: ID!
name: String!
incompleteTodos: Int
totalTodos: Int
}
type Query {
queryTodoListSummary: [TodoListSummary] @custom(dql:"""
query {
var(func: type(TodoList)) {
incompleteCount as count(TodoList.todos @filter(eq(Todo.completed, false)))
}
queryTodoListSummary(func: uid(incompleteCount), orderdesc: val(incompleteCount)) {
id: uid
name: TodoList.name
incompleteTodos: val(incompleteCount)
totalTodos: count(TodoList.todos)
}
}
""")
}
Now, let's go over what we just did.
First, we added the TodoListSummary
type, which represents the data we need to display the summary for each TodoList
in our summary screen. We added @remote
directive to this type, to make sure the CRUD API isn't generated for it.
Then, we added a query called queryTodoListSummary
which returns a list of TodoListSummary
. This query has the @custom
directive which indicates that it is a custom query. The dql
argument in the directive specifies the DQL query which will be run by Dgraph to fetch the results for this GraphQL query.
To understand the details of how to write such DQL queries, you can look at the docs for Custom DQL. But, for now, let's just understand what the DQL query does. This DQL query orders the TodoList
s in descending order of incomplete todos they have and maps the result to TodoListSummary
type.
This query can now be used to render the summary screen for TodoList
s.
Let's play with our backend now. First of all, let me set the GraphQL schema:
![](upload://jch8N4vl7MgWY89KNVTAqvjVHiH.png)
Now, let's go to the API Explorer
tab and add some TodoList
s containing some Todo
s using this sample mutation:
mutation {
addTodoList(input: [
{
name: "Learning GraphQL"
todos: [
{value: "Get a Slash GraphQL account", completed: true},
{value: "Deploy a GraphQL backend", completed: true},
{value: "Learn to use custom DQL queries", completed: true},
{value: "Build a React app", completed: false},
{value: "Learn more GraphQL", completed: false}
]
}
{
name: "Home tasks"
todos: [
{value: "Buy groceries", completed: false},
{value: "Clean rooms", completed: false},
{value: "Iron clothes", completed: false}
]
}
{
name: "Office tasks"
todos: [
{value: "Write blog", completed: true},
{value: "Get blog reviewed", completed: true},
{value: "Publish the blog", completed: true},
{value: "Attract customers", completed: true},
]
}
]) {
todoList {
id
name
todos {
id
value
completed
}
}
}
}
It will give us back the results of the mutation:
![](upload://yFuZpnbXfJO00U6DF8KKV9hv1dM.png)
Now, let's use our custom query to fetch the summary screen results. So, I am going to run the following query on the Slash GraphQL backend:
query {
queryTodoListSummary {
id
name
incompleteTodos
totalTodos
}
}
Here is what we get back:
![](upload://rSZ9dZs8QW0iVqZe5RSjZKOPyMJ.png)
See, how easy it is to run custom queries in Slash GraphQL. We got the data that we need to render the summary screen in the order we wanted it to appear.
Summary
We just learned how to use custom DQL queries in Slash GraphQL. You can learn more about DQL from the DQL docs, play with it in the tour, and learn how to use it in your GraphQL API from the Custom DQL in GraphQL docs.
When the auto-generated GraphQL CRUD API doesn't suit your needs, DQL will always be there for the rescue!
ReferencesTop image: Dust and the Helix NebulaThis is a companion discussion topic for the original entry at https://dgraph.io/blog/post/custom-dql-slash-graphql/