This is a really quick guide to GraphQL for REST developers. It's was prompted by a comment on the #believeinserverless Discord channel.
TLDR;
Endpoints
GraphQL, unlike REST, only has one endpoint. It's usually called /graphql
and it accepts an HTTP POST request. The post body is a JSON object that looks like
{
"query": "...",
"operationName": "...",
"variables": { "someVariable": "someValue", ... }
}
The response is then
{
"data": { ... },
"errors": [ ... ]
}
Queries and Mutations
GraphQL has three type of operation with the main two being query
and mutation
.
Query
A query is used when you want to fetch data. Your query is going to look something like:
{
query FetchCustomer($id: ID) {
customer(id: $id) {
name
email
address {
street
city
state
country
}
}
}
}
This is a query
with the operation named FetchCustomer
that uses a variable id
to find the customer. It then returns the fields name
and email
from the customer and street
, city
, state
and country
from the customers address
.
Coming from a REST API the idea of specifying the fields you want might seem strange but this is the way. In the REST world this response is usually predetermined with the API developer. The other thing that might seem odd is being able to content objects and fetch related data. In this case we traversed from the customer
to the address
. With a REST API I may have needed to make two API calls to different endpoints.
What you get back in the data field is a JSON object with the data in the same structure you requested.
{
"data": {
"customer": {
"name": "John Smith",
"email": "john@example.com",
"address": {
"street": "1 Australia St",
"city": "Sydney",
"state": "NSW",
"country": "Australia"
}
}
}
}
Before proceeding it's worth pointing out that GraphQL has nullable and non-nullable types. Let's assume that address
was nullable and there wasn't an address. What would happen? GraphQL returns null
and doesn't try to fetch the fields for address
so you get
{
"data": {
"customer": {
"name": "John Smith",
"email": "john@example.com",
"address": null
}
}
}
Mutation
Mutations are used when you want to update data. They look similar to queries but have mutation
instead of query
.
{
mutation CreateCustomer($input: CreateCustomerInput) {
id
name
email
address {
street
city
state
}
}
}
My CreateCustomer
assumes I have defined a model CreateCustomerInput
somewhere and that the result is customer record. Like the query example I need to tell it what data I want returned.
How do I know what to send?
The GraphQL API will have a schema. This schema may be accessible from the /graphql
endpoint using introspection. Tools often use this to provide strong typing for queries.
The good news is that a well designed schema is usually easy to navigate once you see the documentation from the introspection. Unfortunately many developers, especially building internal API's, put minimal though into their schema and the result can be a disaster.
Well designed schemas all follow a naming pattern (which one doesn't matter) and there tends to be strong parallels between GraphQL and what the equivalent REST API would have been. Let's assume we use the pattern resource + action.
REST | GraphQL | Type |
GET /customers | customers | query |
POST /customers | customerCreate | mutation |
GET /customers/:id | customer(id) | query |
PUT /customers/:id | customerUpdate(id, other) | mutation |
DELETE /customers/:id | customerDelete(id) | mutation |
POST /customers/:id/activate | customerActivate(id) | mutation |
Subscriptions
Queries and mutations allow you to fetch data but what if you want to be notified when data changes? For that GraphQL has subscription
.
The subscription operation looks like queries and mutations but your are actually telling the server to push changes to you when they occur. This is commonly done by setting up a websocket connection so that the server can push data to you in response to mutations.
Where next?
This has been a super fast guide to GraphQL for REST developers. The goal wasn't to teach you everything about GraphQL but just give you enough information that you can have a reasonable conversation with special person in your life who won't shut up about how wonderful GraphQL is. BTW: They're right!
If you want to learn more a good starting point is How to GraphQL.