GraphQL is a query language for your API. It was open-sourced by Facebook in 2015 and ever since then gained immense popularity as an alternative to REST. GraphQL was created to have better communication between the client and the server. In this blog post, we are going to learn what a GraphQL query is all about, and even write a few ourselves.
You can think of a GraphQL query like a GET request in REST. GraphQL queries are used to query the GraphQL server for the data that the client needs. What is interesting about GraphQL is that clients can write custom made queries based on the individual client’s needs. This means that GraphQL enables the client to ask for exactly what they want using a query and also returns a response with only what was asked. This approach gives the client more power.
To understand this further let’s explore the concepts that make a GraphQL Query.
To demonstrate and learn GraphQL queries, I am going to use the GitHub API that is available to the public. You can follow along by opening https://developer.github.com/v4/explorer/. Make sure you are signed in to your GitHub account to run the queries.
On the GitHub GraphQL explorer, we can start typing our queries on the left side and hit play to see the JSON response on the right side. We can also browse through the documentation of the API on the right side. The explorer is a great way to write queries against GraphQL APIs.
A GraphQL Query is all about asking for specific fields on objects.
A GraphQL query is composed of fields. I am going to write our first query against the GitHub API. In this query, we are querying for the field viewer and within that querying for the field name.
Tip: Hitting Ctrl+Space on the explorer, will show you all the available fields that you can query against the API.
// GraphQL Query { viewer { name } }
This is the GraphQL response that we receive back. Notice here that we got back exactly what we asked for. We got back the name of the viewer in JSON format. All the responses are wrapped in the data object. Great! You wrote your first GraphQL query. Let’s learn more about queries.
// GraphQL Response JSON { "data": { "viewer": { "name": "Adhithi Ravichandran" } } }
Arguments can be passed to the fields and nested objects in GraphQL. This helps in eliminating multiple round-trips to fetch data from the API.
In GraphQL, we have the option to pass argument values to fields, requesting particular data. By doing so, it differs from the REST approach and eliminates the need to have multiple round-trips to multiple endpoints. Multiple round-trips to the API server can be tedious, and performance heavy. With REST, we can only pass a single set of arguments to the URL. Whereas with GraphQL, you can pass arguments to every field and nested objects, completely eliminating multiple API fetches. A single query can fetch all the data we are looking for, from the API.
Let’s now query against the repository field. This field requires us to pass two arguments, owner and name. I am passing google as the owner, and you can pass any other organization of your choice as the argument. Along with this we also need to pass the name of the repository.
// GraphQL Query with Arguments { repository (owner:"google", name:"WebFundamentals") { name owner { id } } }
Our JSON response back from the server is below. We now have the repository information that we requested from the server. You can play around with this query even further, by passing different sets of arguments.
// GraphQL Response JSON { "data": { "repository": { "name": "WebFundamentals", "owner": { "id": "MDEyOk9yZ2FuaXphdGlvbjEzNDIwMDQ=" } } } }
What if you wanted to query the same field with multiple arguments? There are times when you may be looking for information on the same field, with different sets of arguments. You can do that using Alias in GraphQL.
Aliases help to query for the same field, with different arguments in GraphQL.
Let’s add more to our previous query. Let’s say I want to query the same field repository, but this time I want to query for the Facebook repository in addition to the Google repository. This leads to a field conflict in GraphQL. To overcome that, we introduce aliases.
// GraphQL Query Aliases { // alias "googleRepo" googleRepo: repository (owner:"google", name:"WebFundamentals") { name owner { id } } // alias "facebookRepo" facebookRepo: repository (owner:"facebook", name:"react") { name owner { id } } }
After providing aliases, our query is now error-free and can be run. The JSON response comes back with data for both the arguments on the same field. Each response is wrapped within the alias name. We have responses inside the googleRepo and facebookRepo objects.
// GraphQL JSON Response { "data": { "googleRepo": { "name": "WebFundamentals", "owner": { "id": "MDEyOk9yZ2FuaXphdGlvbjEzNDIwMDQ=" } }, "facebookRepo": { "name": "react", "owner": { "id": "MDEyOk9yZ2FuaXphdGlvbjY5NjMx" } } } }
A useful concept while writing GraphQL queries is fragments. If you notice that your query has many repetitive fields in multiple areas, you can consolidate them into a reusable unit called a fragment.
Fragments let you build multiple fields, and include them in multiple queries. It’s like a function that is also a reusable unit.
Let’s take a look at the query below. Notice that we are querying for the same fields inside the owner field multiple times. This is a good place to use a fragment.
{ googleRepo: repository (owner:"google", name:"WebFundamentals") { name owner { id, avatarUrl resourcePath url } } facebookRepo: repository (owner:"facebook", name:"react") { name owner { id, avatarUrl resourcePath url } } }
We can rewrite our query to use a fragment. Fragments are created with the keyword fragment and can take a unique name. This is the same concept as writing a function in a programming language.
We can create a fragment called ownerInfo. While creating fragments we have to let GraphQL know, on which field it is created. In our case, we are creating the fragment on the RepositoryOwner field. Within our fragment definition, we can include all the fields that we are querying for on the RepositoryOwner object. We are adding id, avatarUrl, resourcePath and url as fields to our fragment.
You can then use the fragment within the query by using the … operator and providing the fragment’s name as shown below:
// GraphQL Query with fragments { googleRepo: repository(owner: "google", name: "WebFundamentals") { name owner { ...ownerInfo //fragment } } facebookRepo: repository(owner: "facebook", name: "react") { name owner { ...ownerInfo //fragment } } } // fragment ownerInfo for RepositoryOwner fields fragment ownerInfo on RepositoryOwner { id avatarUrl resourcePath url }
The code shown below is the JSON response after using a fragment. Notice, that there won’t be any visible changes to the response returned with the use of fragments. Fragments simply make your query look clean and readable. It has no effect on the query response that comes back.
// GraphQL JSON Response { "data": { "googleRepo": { "name": "WebFundamentals", "owner": { "id": "MDEyOk9yZ2FuaXphdGlvbjEzNDIwMDQ=", "avatarUrl": "https://avatars1.githubusercontent.com/u/1342004?v=4", "resourcePath": "/google", "url": "https://github.com/google" } }, "facebookRepo": { "name": "react", "owner": { "id": "MDEyOk9yZ2FuaXphdGlvbjY5NjMx", "avatarUrl": "https://avatars3.githubusercontent.com/u/69631?v=4", "resourcePath": "/facebook", "url": "https://github.com/facebook" } } } }
So far, we have been writing queries without providing a name to our query. Providing a name to the query will ensure readability when there are multiple queries.
Operation name is a meaningful and explicit name for your GraphQL operation.
Let’s give a name to our query here. We can use the keyword query and provide a name of our choice.
query repos{ googleRepo: repository(owner: "google", name: "WebFundamentals") { name owner { ...ownerInfo } } }
I hope you enjoyed writing some GraphQL queries. If you are interested in further learning about GraphQL and getting a big-picture overview of GraphQL, you can check out my course on Pluralsight on GraphQL.
Other Resources:
https://graphql.org/
https://graphql.org/learn/
https://www.graphql.com/
If you have any comments, please post them below and share this post with your team and friends.
LogRocket is like a DVR for web and mobile apps, recording literally everything that happens on your site. Instead of guessing why problems happen, you can aggregate and report on problematic GraphQL requests to quickly understand the root cause. In addition, you can track Apollo client state and inspect GraphQL queries' key-value pairs.
LogRocket instruments your app to record baseline performance timings such as page load time, time to first byte, slow network requests, and also logs Redux, NgRx, and Vuex actions/state. Start monitoring for free.Hey there, want to help make our blog better?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowHandle frontend data discrepancies with eventual consistency using WebSockets, Docker Compose, and practical code examples.
Efficient initializing is crucial to smooth-running websites. One way to optimize that process is through lazy initialization in Rust 1.80.
Design React Native UIs that look great on any device by using adaptive layouts, responsive scaling, and platform-specific tools.
Angular’s two-way data binding has evolved with signals, offering improved performance, simpler syntax, and better type inference.