GraphQL: Queries, Mutuations and Subscriptions

In my first article, I talked about GraphQL types and relationships. This time, I’ll be focusing on queries, mutations and subscriptions. lI’ll also provide an overview of how variables are used. This is all necessary setup for the final piece in this series, where I’ll show you how to combine all this knowledge together to create a schema for our example application—a document management system.Let's go!Queries are used by the client to request the data it needs from the server. Unlike REST APIs where there’s a clearly defined structure of information returned from each endpoint, GraphQL always exposes only one endpoint, allowing the client to decide what data it really needs from a predefined pattern. Here’s an example:[pastacode lang="javascript" manual="%7B%0A%0A%C2%A0Users%20%7B%0A%0A%C2%A0%C2%A0%C2%A0%C2%A0name%0A%0A%C2%A0%7D%0A%0A%7D" message="" highlight="" provider="manual"/]The Users field in our query above is called the root field of the query. Anything that comes after the root field is known as the payload.Since we only added name in the payload, the query will return a list of all the users in the database like this:[pastacode lang="javascript" manual="%7B%0A%0A%E2%80%9CUsers%E2%80%9D%3A%20%5B%0A%0A%C2%A0%C2%A0%7B%E2%80%9Cname%E2%80%9D%3A%20%E2%80%9CKingdom%E2%80%9D%7D%2C%0A%0A%C2%A0%C2%A0%7B%E2%80%9Cname%E2%80%9D%3A%20%E2%80%9CJohn%E2%80%9D%7D%2C%0A%0A%C2%A0%C2%A0%7B%E2%80%9Cname%E2%80%9D%3A%20%E2%80%9CJanet%E2%80%9D%7D%2C%0A%0A%C2%A0%C2%A0%7B%E2%80%9Cname%E2%80%9D%3A%20%E2%80%9CDan%E2%80%9D%7D%2C%0A%0A%5D%0A%0A%7D%0A%0A" message="" highlight="" provider="manual"/]You’ll notice that the query only returned the names of the users; this is because in the query payload, we specified that we need only the name of each user. This capability is described by GraphQL as ask for what you need and you’ll get exactly that.Now assuming we need more information about the users, we can decide to add username to the payload[pastacode lang="javascript" manual="%7B%0A%0AUsers%20%7B%0A%0A%C2%A0%C2%A0name%0A%0A%C2%A0%C2%A0username%0A%0A%7D%0A%0A%7D" message="" highlight="" provider="manual"/]now the server will include the username of each user in its response.[pastacode lang="javascript" manual="%7B%0A%0A%E2%80%9CUsers%E2%80%9D%3A%20%5B%0A%0A%C2%A0%C2%A0%7B%E2%80%9Cname%E2%80%9D%3A%20%E2%80%9CKingdom%E2%80%9D%2C%20%E2%80%9Cusername%E2%80%9D%3A%20%E2%80%9Dkingisaac95%E2%80%9D%7D%2C%0A%0A%C2%A0%C2%A0%7B%E2%80%9Cname%E2%80%9D%3A%20%E2%80%9CJohn%E2%80%9D%2C%20%E2%80%9Cusername%E2%80%9D%3A%20%E2%80%9Cjony%E2%80%9D%7D%2C%0A%0A%C2%A0%C2%A0%7B%E2%80%9Cname%E2%80%9D%3A%20%E2%80%9CJanet%E2%80%9D%2C%20%E2%80%9Cusername%E2%80%9D%3A%20%E2%80%9Cjan%E2%80%9D%7D%2C%0A%0A%C2%A0%C2%A0%7B%E2%80%9Cname%E2%80%9D%3A%20%E2%80%9CDan%E2%80%9D%2C%20%E2%80%9Cusername%E2%80%9D%3A%20%E2%80%9Cdan_d%E2%80%9D%7D%2C%0A%0A%5D%0A%0A%7D" message="" highlight="" provider="manual"/]This way we have more flexibility over the data we receive from the server, which is immensely valuable for many reasons. For example, assuming we want to request the server to send information of only the last two users who were added, we can use arguments to specify it like this:[pastacode lang="javascript" manual="%7B%0A%0AUsers(last%3A%202)%20%7B%0A%0A%C2%A0%C2%A0name%0A%0A%C2%A0%C2%A0username%0A%0A%7D%0A%0A%7D" message="" highlight="" provider="manual"/]Note: Zero or more arguments (like last: 2) can be provided for each field in GraphQL. Each argument passed to any field must be defined in the schema.Thus the server will only return:[pastacode lang="javascript" manual="%7B%0A%0A%E2%80%9CUsers%E2%80%9D%3A%20%5B%0A%0A%C2%A0%C2%A0%7B%E2%80%9Cname%E2%80%9D%3A%20%E2%80%9CJanet%E2%80%9D%2C%20%E2%80%9Cusername%E2%80%9D%3A%20%E2%80%9Cjan%E2%80%9D%7D%2C%0A%0A%C2%A0%C2%A0%7B%E2%80%9Cname%E2%80%9D%3A%20%E2%80%9CDan%E2%80%9D%2C%20%E2%80%9Cusername%E2%80%9D%3A%20%E2%80%9Cdan_d%E2%80%9D%7D%0A%0A%5D%0A%0A%7D" message="" highlight="" provider="manual"/]Also assuming we have defined an argument in our schema for getting a single document from its title, we can pass in the title as an argument, like this:[pastacode lang="javascript" manual="%7B%0A%0ADocuments(title%3A%20%22First%20post%22)%20%7B%0A%0A%C2%A0%C2%A0title%0A%0A%C2%A0%C2%A0content%0A%0A%7D%0A%0A%7D%0A%0A" message="" highlight="" provider="manual"/]As expected, this query returns the document whose title matches our argument:[pastacode lang="javascript" manual="%7B%0A%0A%E2%80%9CDocuments%E2%80%9D%3A%20%5B%0A%0A%C2%A0%C2%A0%7B%E2%80%9Ctitle%E2%80%9D%3A%20%E2%80%9CFirst%20post%E2%80%9D%2C%20%E2%80%9Ccontent%E2%80%9D%3A%20%E2%80%9CThis%20is%20the%20first%20post.%22%7D%0A%0A%5D%0A%0A%7D" message="" highlight="" provider="manual"/]Passing arguments the way we just did is helpful, but in most instances, the arguments needs to be dynamic. GraphQL provides a way for us to pass in dynamic values as arguments— by treating them as variables.Variables are used to factor dynamic values out of the query and pass them as a separate dictionary.For example, if we have a search field where a user types in the title of documents he or she wants to view. To allow that, we’d use variables like this: [pastacode lang="javascript" manual="query%20Documents(%24title%3A%20String)%20%7B%0A%0Adocument(title%3A%20%24title)%20%7B%0A%0A%C2%A0%C2%A0title%0A%0A%C2%A0%0A%0A%C2%A0%C2%A0content%0A%0A%7D%0A%0A%7D" message="" highlight="" provider="manual"/]($title: String) is the variable definition. title is the variable name and it is prefixed by $, followed by the type in this case String. You can learn more about variables and how they’re used from GraphQL docs.We’ve seen how to retrieve data from the server using queries, but how do we create, update and delete data in GraphQL?Mutations are the key. In GraphQL, mutations are used to CUD:

  • Create new data
  • Update existing data
  • Delete existing data

The syntax for mutations look almost the same as queries, but they must start with the mutation keyword. Here’s an example that’ll allow us create a new user:[pastacode lang="javascript" manual="mutation%20%7B%0A%0AcreateUser(name%3A%20%E2%80%9CDoe%E2%80%9D%2C%20username%3A%20%E2%80%9Cjdoe%E2%80%9D)%20%7B%0A%0A%C2%A0%C2%A0name%0A%0A%C2%A0%C2%A0username%0A%0A%7D%0A%0A%7D" message="" highlight="" provider="manual"/]Notice that the mutation has a root field and payload, just like a query. There are also two arguments passed to the mutation — name and username.To be able to manage the data of our users effectively, we need to assign a unique identity to each user.GraphQL has a type ID that can be attached to a field. When that is done, the server will automatically generate a unique id for each new object (user).Recall from the previous articlethat we created a GraphQL type called User, and now we can update it to include an id field as follows:[pastacode lang="javascript" manual="type%20User%20%7B%0A%0Aid%3A%20ID!%0A%0Aname%3A%20String!%0A%0Ausername%3A%20String!%0A%0A%7D" message="" highlight="" provider="manual"/]Now we can update the mutation by passing only the id to the payload. That way the server will return the id of the user we just created.[pastacode lang="javascript" manual="mutation%20%7B%0A%0AcreateUser(name%3A%20%E2%80%9CDoe%E2%80%9D%2C%20username%3A%20%E2%80%9Cjdoe%E2%80%9D)%20%7B%0A%0A%C2%A0%C2%A0id%0A%0A%7D%0A%0A%7D" message="" highlight="" provider="manual"/]Subscriptions are a way to create and maintain real time connection to the server. This enables the client to get immediate information about related events. Basically, a client subscribes to an event in the server, and whenever that event is called, the server will send the corresponding data to the client.Subscriptions are event based. Here’s how they work:Let’s say our document management app allows users to comment on each document and the comments need to be updated in real time. This means:

  • For the initial page load, we need to fetch the previous comments using GraphQL queries.
  • Next, we’ll listen for the new comment and get them through a subscription.
  • We update the UI with a notification that there’s a new comment.

We can also create a subscription that notifies users when a comment is deleted. In our example, we will want to get updates from the server whenever a new user is created that way we can update the client automatically without having to make a call for it.Here is an example subscription:[pastacode lang="javascript" manual="subscription%20%7B%0A%0AnewUser%20%7B%0A%0A%C2%A0%C2%A0name%0A%0A%C2%A0%C2%A0username%0A%0A%7D%0A%0A%7D" message="" highlight="" provider="manual"/]

Conclusion

In this article we introduced the concepts of queries, mutations and subscriptions. As mentioned in the introduction, we will combine all these concepts together to create a schema for our example application—a document management system—in the next article.Special thanks to Peggy Rayzis and Eric Baer for reviewing this article.

Related posts

The latest articles from Andela.

Visit our blog

How to transition your company to a remote environment

Organizations need to embrace a remote-first mindset, whether they have a hybrid work model or not. Remote-first companies can see a boost in more employee morale and productivity. Here’s how to successfully shift to a remote-first environment.

Andela Appoints Kishore Rachapudi as Chief Revenue Officer

Andela scales to meet rising demand among companies to source technical talent in other countries for short or long-term projects.

How Andela's all-female learning program in Lagos is still transforming careers ten years on

In 2014, we launched an all-female cohort in Lagos, Nigeria, to train women in software engineering and development. We spoke to three of the trailblazing women from cohort 4 to find out how the program still inspires their technology careers 10 years later.

We have a 96%+
talent match success rate.

The Andela Talent Operating Platform provides transparency to talent profiles and assessment before hiring. AI-driven algorithms match the right talent for the job.