In this blog post, we are going to discuss three important GraphQL Operations concepts: queries, mutation, and subscription. GraphQL queries are used to fetch data from a GraphQL server, similar to a GET request. The mutation is used to update data on a GraphQL server and subscription is used to listen for any event on the server.
We will use one public GraphQL API endpoint holding the information of all StarWars series. Open this link on any web browser, it will open one web page like below :
This is âGraphiQLâ, an user interface tool to run GraphQL queries. You can write your query on the left side and get its output on the right side by hitting the âPlayâ button.
To check what GraphQL schemas are available, click on the âDocsâ button on the top right corner. It will show you one line as âquery: Rootâ. Click on âRootâ to get the available schemas. It will show you something like below:
As you can see, we have different types of GraphQL schemas defined. For example, âallFilmsâ takes four optional parameters âafterâ, âfirstâ, âbeforeâ, and âlastâ and it returns one âFilmsConnectionâ object. You can click on this object name to get the list of all available fields. Isnât it really easy?
Two more buttons are available on GraphiQL: âPrettifyâ and âhistoryâ. The âPrettifyâ button is for reformatting the code and âhistoryâ is for checking the previous queries.
Write one basic query:
Letâs get the list of all peoples using the âallPeopleâ schema:
allPeople( after: String first: Int before: String last: Int) : PeopleConnection
It takes four optional parameters and returns one âPeopleConnectionâ with the following items:
- pageInfo: PageInfo!
- edges: [PeopleEdge]
- totalCount: Int
- people: [Person]
We are not going to fetch all of the items, instead, we will request for only the âtotalCountâ and âpeopleâ. âtotalCountâ is an integer holding the total number of values and âpeopleâ is an array holding âPersonâ objects. You can click on the âPersonâ object in the document explorer to check its included fields.
Copy paste the following query on the left side and hit the play button:
{ allPeople { totalCount people { id name gender } } }
It will return one output JSON like below:
{ data: { allPeople: { totalCount: 87, people: [ { id: "cGVvcGxlOjE=", name: "Luke Skywalker", gender: "male" }, { id: "cGVvcGxlOjI=", name: "C-3PO", gender: "n/a" }, { id: "cGVvcGxlOjM=", name: "R2-D2", gender: "n/a" }, ... ... ... ] } } }
As you can see here, we got the âtotalCountâ value and a list of âPersonâ with âidâ, ânameâ and âgenderâ for each. âtotalCountâ is of Scalar type and âPersonâ is an object type. Total of five scalar types are available in GraphQL: Int, Boolean, Float, String, and ID. Inside each âPersonâ object, we are accessing only âidâ, ânameâ and âgenderâ fields, but it also holds many other different fields including different objects. This is the main advantage of GraphQL, we can get what we are asking for.
Passing an argument:
We can also pass one argument with a query. For example, for the following schema:
person(id: ID personID: ID): Person
We can pass one âidâ or âpersonIDâ to get the required âPersonâ object. Letâs use the id xcGVvcGxlOjE=x from the above example:
{ person(id: "cGVvcGxlOjE=") { name gender } }
Run this query and it will return the following object:
{ "data": { "person": { "name": "Luke Skywalker", "gender": "male" } } }
The above queries are known as anonymous queries or queries without any name. We can also set one name for a GraphQL query like below:
query GetPerson { person(id: "cGVvcGxlOjE=") { name gender } }
This query will return the same result as the previous one.
Using variables:
We have learned how to pass one argument to a GraphQL query. But, instead of passing one argument directly to a GraphQL query, we can provide one variable name in the query and execute that query separately. GraphiQL also provides one separate portion to add query variables to a variable query.
The variable name should start with â$â and the variable type should be mentioned in the query. For example, we can rewrite the above âGetPersonâ query as below:
query GetPerson($id: ID) { person(id: $id) { name gender } }
Here, we are passing one âidâ of type âIDâ to the âGetPersonâ query. The same âidâ is used in the âpersonâ query call inside.
We can execute the above query like below:
{"id": "cGVvcGxlOjE="}
On GraphiQL, you can execute it like below:
As you can see that the output is the same as like the previous query.
Skip or include data based on a variable:
GraphQL provides two directives to include or skip specific fields based on the value of a variable. For example,
query GetPerson($includeGender: Boolean!, $id: ID) { person(id: $id) { name gender @include(if: $includeGender) } }
We have two variables in this query. âidâ is of type âIDâ and âincludeGenderâ is of type âBooleanâ. One more line we have changed here :
gender @include(if: $includeGender)
It means that the âgenderâ field will be included in the output only if âincludeGenderâ is âtrueâ. For example,
{"includeGender": false,"id": "cGVvcGxlOjE="}
For these variables, the output will be:
{ "data": { "person": { "name": "Luke Skywalker" } } }
As you can see here, the âgenderâ field is not included in the output.
Similar to â@includeâ directive, we have one more directive called â@skipâ. It works just the opposite to â@includeâ, i.e. it will include a field only if the value of â@skipâ is false.
We can write the above query as below :
query GetPerson($excludeGender: Boolean!, $id: ID) { person(id: $id) { name gender @skip(if: $excludeGender) } }
Here, âexcludeGenderâ should be âfalseâ to include the âgenderâ field in the output.
Getting multiple objects:
We can also fetch multiple objects with different values in the same query.
query GetPerson { person1: person(id: "cGVvcGxlOjE=") { name gender } person2: person(id: "cGVvcGxlOjU=") { name gender } }
This will fetch two objects for two different âidâs.
{ "data": { "person1": { "name": "Luke Skywalker", "gender": "male" }, "person2": { "name": "Leia Organa", "gender": "female" } } }
In this query, we are repeating the inner fields of the query on both âperson1â and âperson2â i.e. we are writing ânameâ and âgenderâ two times. We can extract the inner query part and use it instead. This part is called âfragmentâ in GraphQL.
query GetPerson { person1: person(id: "cGVvcGxlOjE=") { ...userInfo } person2: person(id: "cGVvcGxlOjU=") { ...userInfo } }
fragment userInfo on Person { name gender }
Here, we have defined one new fragment âuserInfoâ. âon Personâ means that the fragment is defined on âPersonâ type. This query will fetch the same output as the previous one. Fragment is really useful if you donât want to repeat the same code.
Using Aliases:
Aliases is used to change the field name of the return data. For the below query,
query GetPerson { person(id: "cGVvcGxlOjE=") { name } }
x
It will return the ânameâ of the person with the provided id.
{ "data": { "person": { "name": "Luke Skywalker" } } }
Using aliases, we can change the âidâ name of the return data. It is used like âaliases name : field nameâ
query GetPerson { person(id: "cGVvcGxlOjE=") { personName: name } }
This query will return:
{ "data": { "person": { "personName": "Luke Skywalker" } } }
Using aliases, you can make changes to the API output on the client side without changing anything on the server.
Mutation:
We can use mutation to perform any of the following:
x Create a new data
x Update an existing data
x Delete a data
Writing a mutation is almost similar to the queries. The only difference is that we can write queries using an empty curly bracket (anonymous query) or using the âqueryâ keyword and its name. For mutation, we need to use the âmutationâ keyword always.
The above GraphQL API doesnât provide any mutation operation as it is a public API. But if you have your own GraphQL server, you can define one mutation to create a new person like below :
mutation { createPerson(personName: âLuke Skywalkerâ, gender: âmaleâ) { id } }
This mutation operation is taking two arguments to create one âPersonâ. Both arguments are of string type. The GraphQL server will create one âPersonâ with a unique âidâ and returns the âidâ with its response. Similar to the queries, you can ask for what you want in the response. In this example, the client can store the âidâ locally and use it on any delete or update request for the created âPersonâ object.
Subscription:
Subscription is another powerful feature of GraphQL. Basically, the client can subscribe to an event of the server and whenever the event is executed, the server will notify the client.
For example, if we are developing a chat application, we can use a subscription to listen for any new chat in a chat-room. We can update the UI if any new chat notification is received. Similarly, for any other real-time monitoring application, a subscription can be used.
The âsubscriptionâ query is similar to âmutationâ :
subscription { newComment { comment } }
Conclusion:
In this tutorial, we have learned about GraphQL query, mutation and subscription. This Github repo contains a list of public GraphQL APIs. You can try with different API endpoints to get familiar with different types of queries.
Tutorial Index:
- GraphQL Tutorial #1 -Introduction
- GgraphQL Tutorial #2 x Setting Basic Project in GraphQL
- GraphQL Tutorial #3 x GraphQL Components
- GraphQL Tutorial #4 x GraphQL Operations
- GraphQL Tutorial #5 x Introduction to Apollo GraphQL
- GraphQL Tutorial #6 x 51 Most Important GraphQL Interview QxA