Now you’ve set up your schema, but how do you use your GraphQL endpoints?
Note
This tutorial assumes that you’ve set up your GraphQL schema. If you haven’t, please take a look at the 10 minute guide to GraphQL schema
Generated Resolvers
To query or change data in a GraphQL server, you need to call one of the ‘functions’ defined on your server. These functions are names resolvers, and Dgraph automatically generates up to five resolvers for each type defined in your schema.
For example, if we define a Tweet
type in the schema, we get the following resolvers:
-
GetTweet
(Only if an ID field was defined) QueryTweet
AddTweet
UpdateTweet
DeleteTweet
Accessing your endpoints
The quickest way to start playing around with your endpoint is to download GraphQL Playground. Once one of these is downloaded, point it at your Slash endpoint. Your GraphQL endpoint can be found on the dashboard. It will look something like: https://example.us-west-2.aws.cloud.dgraph.io/graphql
.
![](upload://cOTBBlCWyVDASrb779dgmharoEi.png)
If you open up the docs tab on the right side, you’ll see that GraphQL playground has pulled all the possible resolvers that our server supports.
Mutations
GraphQL operations can be of two types, queries and mutations. Queries are defined as read-only operations, while mutations are write operations. We’ll start with mutations, so we have something to query in the next step.
The first operation that we want to do is get some data inserted into our database. Let’s add some users, and also create some tweets at the same time. You can copy and paste the following mutation into GraphQL playground.
mutation {
addUser(input: [
{ handle: "firstuser", name: "First User!", tweets: [
{ text: "This is the first tweet ever!" },
{ text: "This is the second tweet ever!" },
{ text: "I'm getting kind of bored..." },
] },
{ handle: "dgraphlover", name: "I LOVE DGRAPH", tweets: [
{ text: "DGRAPH IS GREAT!" },
{ text: "DID I EVER TELL YOU GUYS HOW MUCH I LIKE DGRAPH!" },
] },
{ handle: "cooltweeter", name: "Follow for cool tweets", tweets: [
{ text: "Anyone have any cool feeds I can follow?" },
] }
]) {
users {
handle
}
}
}
Note that every mutation query must start with mutation
, as seen above.
In the above example, we call the addUser
resolver on our server, and we are passing in a list of users to the create resolver, as the input
parameter. We’re also passing a list of tweets for each user, and Dgraph is smart enough to create all the relationships between the tweets and users.
The second part of the mutation, user { id }
is what we want to return from the query.
Now, let’s say firstuser
wants to update his name, as he wants to leave his old life behind. Let’s create another query to update their name.
mutation {
updateUser(
filter: { handle: { eq: "firstuser" }},
set: { name: "Not First User" }}
) {
user {
handle
}
}
}
Now we’ve updated the user’s name. Deleting is handled similar to update, but it doesn't take a ‘set’ parameter.
Queries
We now have some data into our database, so let’s query the data. We've actually covered a lot of the basics of querying when updating data in the previous section. First, let’s do a simple query to pull all users.
{
queryUsers {
handle
name
tweets {
id
text
}
}
}
Run this query, and you will get a list of users stored in the database, as well as a list of their tweets. By omitting the (filter: ...)
parameter, we are asking Dgraph to return all users.
Filtering
Let's delve a bit deeper into filtering. In the last section, we used some simple filters to update a user.
One important thing to note is that the options available in the filter
parameter depend on the @search
directives that are defined on this type. For example, adding the @search(by: [fulltext])
directive to Tweet.text
allows us to use anyoftext
and alloftext
filters when filtering on the Tweet.text
field. A quick example is searching for all tweets that contain the words “tweet” or “ever”:
mutation {
queryTweet(filter: { text: { anyoftext: "tweet ever" }} {
text
user
}
}
Each index added to the @search
directive unlocks new possibilities for filtering. For more information, take a look at the GraphQL query docs.
Nested filtering
So far, we've only been filtering on the top level. What if we want to filter on nested types? For example, we want to pull all users, and a list of their tweets that contain “tweet ever”. We would query as so:
{
queryUser {
handle
name
tweets(filter: { text: { alloftext: "tweet ever" }}) {
text
}
}
}
As you can see, we can use the same filtering structure as before on nested objects.
Let's make this query a bit more complex. What if we want to only see users that have at least one of these tweets? For that, we can use the @cascade
directive.
{
queryUser @cascade {
handle
name
tweets(filter: { text: { alloftext: "tweet ever" }}) {
text
}
}
}
Now, we will only get firstuser
back, as he is the only one that fulfills our filter criteria.
Ordering
Ordering in GraphQL queries is extremely simple. Simply add an offset
param to your query. The offset
is provided with asc
and desc
fields, and then you pass in the field to order by. The example below, which orders tweets from newest to oldest, should be self explanatory:
{
queryTweet(order: { desc: id }) {
text
user {
handle
name
}
}
}
Pagination
Pagination in GraphQL is also very simple. It's actually as simple as adding first
and offset
params. offset
is the number of records in the beginning we want to skip, and first
is the number of records we want to return. For example, let's say we're on the second page of tweets, and each page has 50 tweets. We would query as such:
{
queryTweet(first: 50, offset: 50) {
text
user {
handle
name
}
}
}
And with that, you should now have the skills to mutate and query to your heart's content!
Further Reading
GraphQL Mutation documentation.
If you want to send queries and mutation from your frontend, take a look at Apollo client. Apollo client makes sending GraphQL queries easier, as well as including many cool features such as query caching.
ReferencesTop image: Liftoff to the Red Planet!This is a companion discussion topic for the original entry at https://dgraph.io/blog/post/slash-query-endpoints/