Let’s now look at the GraphQL approach. GraphQL on the server embraces the custom endpoints idea and takes it to its extreme. The server will be just a single endpoint, and the channel does not matter. If we’re doing this over HTTP, the HTTP method certainly wouldn’t matter either. Let’s assume we have a single GraphQL endpoint exposed over HTTP at /graphql

Since we want to ask for the data we need in a single round-trip, we’ll need a way to express our complete data needs for the server. We do this with a GraphQL query:

GET or POST - /graphql?query={...}

A GraphQL query is just a string, but it will have to include all the pieces of the data that we need, and this is where the declarative power comes in.

In English, here’s how we declare our data requirement: we need a person’s name, birth year, their planet’s name, and the titles of all their films. In GraphQL, this translates to:

{

person(ID: ...) {

name,

birthYear,

planet {

name

},

films {

title

}

}

}

Read the English-expressed requirements one more time and compare it to the GraphQL query. It’s as close as it can get. Now compare this GraphQL query with the original JSON data that we started with. The GraphQL query is the exact structure of the JSON data, except without all the “values” parts. If we think of this in terms of a question-answer relation, the question is the answer statement without the answer part.

If the answer statement is:

The closest planet to the Sun is Mercury.

A good representation of the question is the same statement without the answer part:

(What is) the closest planet to the Sun?

The same relation applies to a GraphQL query. Take a JSON response, remove all the “answer” parts (which are the values), and you end up with a GraphQL query very suitable to represent a question about that JSON response.

Now compare the GraphQL query with the declarative React UI we defined for the data. Everything in the GraphQL query is used in the UI, and everything used in the UI appears in the GraphQL query. This is the great mental model of GraphQL. The UI knows the exact data it needs, and extracting that requirement is fairly easy. Coming up with a GraphQL query is simply the task of extracting what’s used as variables directly from the UI. If we invert this model, it would still hold the power. If we have a GraphQL query, we know exactly how to use its response in the UI, because the query will be the same “structure” as the response. We don’t need to inspect the response to know how to use it, and we don’t need any documentation about the API; it’s all built-in.

Star Wars data has a GraphQL API hosted at https://github.com/graphql/swapi-graphql. Go ahead and try to construct our data person object there. There are a few minor differences that we’ll explain later, but here’s the official query you can use against this API to read our data requirement for the view (with Darth Vader as an example):

{

person(personID: 4) {

name,

birthYear,

homeworld {

name

},

filmConnection {

films {

title

}

}

}

}

This request gives us a response structure very close to what our view used, and remember, we’re getting all of this data in a single round-trip.

If you’re interested to learn more about GraphQL (and Relay), I wrote a book about them.