Serverless GraphQL API
Say you're building an app. It needs data from a server. What do you do?
You make a fetch()
request.
fetch("https://swapi.dev/api/people/1/")
.then((res) => res.json())
.then(console.log)
And you get eeeevery piece of info about Luke Skywalker.
{
"name": "Luke Skywalker",
"height": "172",
"mass": "77",
"hair_color": "blond",
"skin_color": "fair",
"eye_color": "blue",
"birth_year": "19BBY",
"gender": "male",
"homeworld": "https://swapi.dev/api/planets/1/",
"films": [
"https://swapi.dev/api/films/2/",
"https://swapi.dev/api/films/6/",
"https://swapi.dev/api/films/3/",
"https://swapi.dev/api/films/1/",
"https://swapi.dev/api/films/7/"
],
"species": ["https://swapi.dev/api/species/1/"],
"vehicles": [
"https://swapi.dev/api/vehicles/14/",
"https://swapi.dev/api/vehicles/30/"
],
"starships": [
"https://swapi.dev/api/starships/12/",
"https://swapi.dev/api/starships/22/"
],
"created": "2014-12-09T13:50:51.644000Z",
"edited": "2014-12-20T21:17:56.891000Z",
"url": "https://swapi.dev/api/people/1/"
}
Frustrating ... all you wanted was his name and hair color. Why's the API sending you all this crap? 🤦♂️
And what's this about Luke's species being 1
? What the heck is 1
?
You make another fetch request.
fetch("https://swapi.dev/api/species/1/")
.then((res) => res.json())
.then(console.log)
You get data about humans. Great.
{
"name": "Human",
"classification": "mammal",
"designation": "sentient",
"average_height": "180",
"skin_colors": "caucasian, black, asian, hispanic",
"hair_colors": "blonde, brown, black, red",
"eye_colors": "brown, blue, green, hazel, grey, amber",
"average_lifespan": "120",
"homeworld": "https://swapi.dev/api/planets/9/",
"language": "Galactic Basic",
"people": [
"https://swapi.dev/api/people/1/",
"https://swapi.dev/api/people/4/",
"https://swapi.dev/api/people/5/",
"https://swapi.dev/api/people/6/",
"https://swapi.dev/api/people/7/",
"https://swapi.dev/api/people/9/",
"https://swapi.dev/api/people/10/",
"https://swapi.dev/api/people/11/",
"https://swapi.dev/api/people/12/",
"https://swapi.dev/api/people/14/",
"https://swapi.dev/api/people/18/",
"https://swapi.dev/api/people/19/",
"https://swapi.dev/api/people/21/",
"https://swapi.dev/api/people/22/",
"https://swapi.dev/api/people/25/",
"https://swapi.dev/api/people/26/",
"https://swapi.dev/api/people/28/",
"https://swapi.dev/api/people/29/",
"https://swapi.dev/api/people/32/",
"https://swapi.dev/api/people/34/",
"https://swapi.dev/api/people/43/",
"https://swapi.dev/api/people/51/",
"https://swapi.dev/api/people/60/",
"https://swapi.dev/api/people/61/",
"https://swapi.dev/api/people/62/",
"https://swapi.dev/api/people/66/",
"https://swapi.dev/api/people/67/",
"https://swapi.dev/api/people/68/",
"https://swapi.dev/api/people/69/",
"https://swapi.dev/api/people/74/",
"https://swapi.dev/api/people/81/",
"https://swapi.dev/api/people/84/",
"https://swapi.dev/api/people/85/",
"https://swapi.dev/api/people/86/",
"https://swapi.dev/api/people/35/"
],
"films": [
"https://swapi.dev/api/films/2/",
"https://swapi.dev/api/films/7/",
"https://swapi.dev/api/films/5/",
"https://swapi.dev/api/films/4/",
"https://swapi.dev/api/films/6/",
"https://swapi.dev/api/films/3/",
"https://swapi.dev/api/films/1/"
],
"created": "2014-12-10T13:52:11.567000Z",
"edited": "2015-04-17T06:59:55.850671Z",
"url": "https://swapi.dev/api/species/1/"
}
That's a lot of JSON to get the word "Human"
out of the Star Wars API ...
What about Luke's starships? There's 2 and that means 2 more API requests ...
fetch("https://swapi.dev/api/starships/12/")
.then((res) => res.json())
.then(console.log)
fetch("https://swapi.dev/api/starships/22/")
.then((res) => res.json())
.then(console.log)
Wanna know how much JSON that dumps? Try a guess. 🙄
You made 4 API requests and transferred a bunch of data to find out that Luke Skywalker is human, has blond hair, and flies an X-Wing and an Imperial Shuttle.
And guess what, you didn't cache anything. How often do you think this data changes? Once a year? Twice?
🤦♂️
GraphQL to the rescue
Here's what the same process looks like with GraphQL.
query luke {
// id found through allPeople query
person(id: "cGVvcGxlOjE=") {
name
hairColor
species {
name
}
starshipConnection {
starships {
name
}
}
}
}
And the API returns what you wanted with 1 request.
{
"data": {
"person": {
"name": "Luke Skywalker",
"hairColor": "blond",
"species": null,
"starshipConnection": {
"starships": [
{
"name": "X-wing"
},
{
"name": "Imperial shuttle"
}
]
}
}
}
}
An API mechanism that gives you flexibility on the frontend, slashes API requests, and doesn't transfer data you don't need?
😲
Write a query, say what you want, send to an endpoint, GraphQL figures out the rest. Want different params? Just say so. Want multiple models? Got it. Wanna go deep? You can.
Without changes on the server. Within reason.
GraphQL client libraries can add caching to avoid duplicate requests. And because queries are structured, clients can merge queries into 1 API call.
I fell in love the moment it clicked.