Let's look at what GraphQL queries look like.
The query language of GraphQL is another of its strong points. It allows clients to define both the data to retrieve and the required shape of that data. This means that a GraphQL client can not only be selective about the data to retrieve, but also dictate how the response should be structured!
Compared to REST, this is incredibly powerful and is standardized by the GraphQL specification. With RESTful APIs, since there is no standard, each and every API can implement (or not) features such as include/exclude, pagination, search, and filtering. With GraphQL, there is one well-defined method for many concepts.
For the following examples, we will use the Star Wars GraphQL API, which you can find here: https://github.com/graphql/swapi-graphql. You can try all of the examples through the playground available here: https://graphql.github.io/swapi-graphql.
We'll start with a basic example where a client wants to retrieve the titles of all of the Star Wars movies:
{ allFilms { films { title } } }
In this example, we have used the allFilms query of the Star Wars API and we have asked to retrieve the title property of each item in the films collection.
Here's an extract of the response that the GraphQL server would return:
{ "data": { "allFilms": { "films": [ { "title": "A New Hope" }, { "title": "The Empire Strikes Back" }, { "title": "Return of the Jedi" }, ... ] } } }
As requested by our GraphQL client, the server has only provided the title property. This feature of GraphQL is incredibly powerful and can greatly improve the network friendliness of your applications.
Let's look at a second example. This time, our client wants to retrieve the ID, name, and species name of each character in the Star Wars movies:
{ characters: allPeople { people { id name species { name } } } }
The syntax is quite straightforward.
In return, the server might respond with the following:
{ "data": { "characters": { "people": [ { "id": "cGVvcGxlOjE=", "name": "Luke Skywalker", "species": { "name": "Human" } }, { "id": "cGVvcGxlOjI=", "name": "C-3PO", "species": { "name": "Droid" } }, ... ] } } }
Again, the server has responded with the data that we asked for (no more, no less) and using the shape and structure that we requested.
This is quite simple, isn't it?
Some queries allow or require parameters to be passed in.
Here's how our client can retrieve the name and birth year of Luke Skywalker (knowing its identifier):
{ person(id: "cGVvcGxlOjE=") { name birthYear } }
Query parameters are simply passed as key-value pairs.
Here is the corresponding response:
{ "data": { "person": { "name": "Luke Skywalker", "birthYear": "19BBY" } } }
GraphQL can do a whole lot more. For instance, clients can use parameters to request specific/alternative data formats, content translations, and so on. Such transformations can spare client-side applications the hassle of doing it themselves and much more still.