GraphQL 101
A TL;DR; of what GraphQL is and how it compares to traditional RESTful APIs.
If you're a front-end developer who's not familiar with GraphQL and it's benefits over "traditional" RESTful APIs - then this post is for you. And if you're not familiar with RESTful APIs either - then this post is still for you. I'll go over the basics of each approach, as well as how they differ. Since this post is aimed at front-end developers I won't be covering how to set up a server with either of these approaches. Instead I'll be covering how to interact with one.
RESTful APIs
Let's start off by going over one of the more common methods of communicating with servers, which is via a RESTful API. For the uninitiated - "REST" stands for REpresentational State Transfer. One of the key components of RESTful APIs is a resource - which represents a distinct piece (or collection) of data. Once your data is segregated into resources, you can make CRUD requests to fetch or manipulate them. For example, let's say you want to interact with an API for pet data. Here is what some of your requests might look like:
CREATE
POST /pets
{
"type": "dog",
"breed": "German Shepherd",
"name": "Max"
}
READ
GET /pets
GET /pets?type=cat
GET /pets/abc123
UPDATE
PUT /pets/abc123
{
"name": "Fido"
}
DELETE
DELETE /pets/abc123
In these examples, the resource ("pets") is described in the URL - and the action you want to take against that resource is described by the HTTP method. Furthermore, resource identifiers are part of the URL as well (e.g. the "abc123" ID).
GraphQL
GraphQL is both a query language and a server-side runtime for executing these queries. Unlike a RESTful API, your typical GraphQL API will only have a single endpoint. Furthermore, it will only utilize a single HTTP method - POST. For comparison, here are some queries that mimic the same requests from the previous example:
CREATE
POST /pets
mutation CreatePet {
createPet(type: "dog", breed: "Chihuahua", name: "Bean") {
type
breed
name
}
}
READ
POST /pets
query GetPets {
pets {
type
breed
name
}
}
POST /pets
query GetPets {
pets(type: "cat") {
type
breed
name
}
}
POST /pets
query GetPets {
pets(id: "abc123") {
type
breed
name
}
}
UPDATE
POST /pets
mutation UpdatePet {
updatePet(id: "abc123") {
name: "Coco"
}
}
DELETE
POST /pets
mutation DeletePet {
deletePet(id: "abc123") {
type
breed
name
}
}
... Notice how we're describing the data we want in the body of the request, rather than through the URL and HTTP method. Now admittedly while this might seem a bit more complicated compared to querying a RESTful API - it does provide a number of benefits. For starters, you can pick and choose exactly what fields you want. For example, compare the request and response for getting a pet with an ID of "abc123":
Request
POST /pets
query GetPets {
pets(id: "abc123") {
type
breed
name
}
}
Response
{
"type": "dog",
"breed": "Chihuahua",
"name": "Bean"
}
... notice how the structure of the response is the same as the structure of our request - it's an object with a "type", "breed", and "name" property. Another big selling point of GraphQL is the ability to combine multiple resources. For example, imagine you also wanted to query the owner of a particular pet, along with its breeder:
Request
POST /pets
query GetPets {
pets(id: "abc123") {
type
breed
name
owner {
name
phone
}
breeder {
name
location
}
}
}
Response
{
"type": "dog",
"breed": "Chihuahua",
"name": "Bean",
"owner": {
"name": "John Doe",
"phone": "999-888-7777"
},
"breeder": {
"name": "Paws of Love",
"location": "Miami, FL"
}
}
Now contrast this with a requesting the same data from a RESTful API, where you have no control over the amount of fields returned - and you have to make multiple requests to combine resources. For example:
Pet Request
GET /pets/abc123
Pet Response
{
"id": "abc123"
"type": "dog",
"breed": "Chihuahua",
"name": "Bean",
"age": 4,
"vaccinated": true,
"owner": "def456",
"breeder": "ghi789"
}
Owner Request
GET /owners/def456
Owner Response
{
"id": "def456",
"name": "John Doe",
"phone": "999-888-7777"
"email": "john.doe@gmail.com",
"location": "Atlanta, GA"
}
Breeder Request
GET /owners/def456
Breeder Response
{
"id": "def456",
"name": "Paws of Love",
"phone": "1-800-444-2211",
"email": "contact@pawsoflove.com",
"location": "Miami, FL",
"licensed": true
}
In Summary
While RESTful APIs are still useful, GraphQL provides a number of advantages - such as allowing you to pick and choose the exact fields you want, as well as allowing you to fetch multiple resources within the same request. This helps reduce the complexity of your front-end code fetching logic, and is also less wasteful as the only data returned in the network request is the data you need.