Until recently, I only had a vague understanding of what GraphQL was. For those that still aren’t sure, please know that it’s ok not to know. There are so many buzzwords and new technologies being created all the time, it would be impossible to keep up with absolutely everything. In fact, it happens so often that IBM even created a chart to document the process that happens each time - this is the hype cycle of emerging technologies:
This chart goes through five phases:
Currently, I think GraphQL is coming out of the Slope of Enlightenment and starting to head into the Plateau of Productivity, which also means it’s worth doing a refresher for those of us that missed it the first time around.
Back in the distant past of 2012, Facebook was having some issues with its app. At the time it was essentially an adaptation of the website, and compared to other natively built apps it simply wasn’t working as well - so they decided it was time to rewrite it.
Originally they intended to use the existing APIs that they had at the time, which like the majority of the industry were mostly REST APIs.
REST is less effective when working with complex data, such as was required by Facebook to populate the newsfeed. To do so could involve a number of separate REST calls; to get the user’s list of friends, to get the recent statuses made by each of those friends, to get the comments for each of the statuses, to get the likes of the comments of the statuses of the friends…
Instead of traditional approaches, GraphQL works by modelling data as a graph, where data types (like users, posts, comments) are nodes, and the relationships between them (like users posting comments) are the edges connecting those nodes. In this structure, you can traverse between related types, much like how you can move across nodes in a graph.
This does not mean that GraphQL is perfect for every scenario - there’s a reason why REST APIs are still more common, as shown in the Postman 2023 State of API Report:
However, if you’re working with complex data and evolving requirements, GraphQL could be the right tool for the job.
API clients tend to have the same structure:
The structure of the response depends on the structure of the query, e.g.
query {
person(personID: "14") {
name
starshipConnection {
starships {
name
}
}
}
}
Returns this:
{
"data": {
"person": {
"name": "Han Solo",
"starshipConnection": {
"starships": [
{
"name": "Millennium Falcon"
},
{
"name": "Imperial shuttle"
}
]
}
}
}
}
(example from the Star Wars GraphQL API.)
Field names can be altered using aliases, so in the above query specifying
fullname: name
returns
"fullname": "Han Solo"
Directives can be used to add logic based on variables - the following would return the value for model
depending on whether fullDetails
was true or false thanks to @include
:
query ($fullDetails: Boolean!){
person(personID: "14") {
fullname: name
starshipConnection {
starships {
name
model @include(if: $fullDetails)
}
}
}
}
Queries can be broken into fragments, the same way that applications are broken into components. If starships
and vehicles
were derived from an overarching Transport
type, the fields within both could be requested like this:
query {
person(personID: "1") {
fullname: name
starshipConnection {
starships {
...vehicleAndStarshipFields
}
}
vehicleConnection{
vehicles{
...vehicleAndStarshipFields
}
}
}
}
fragment vehicleAndStarshipFields on Transport {
name
model
}
Which would return in this format:
{
"data": {
"person": {
"fullname": "Luke Skywalker",
"starshipConnection": {
"starships": [
{
"name": "X-wing",
"model": "T-65 X-wing"
},
{
"name": "Imperial shuttle",
"model": "Lambda-class T-4a shuttle"
}
]
},
"vehicleConnection": {
"vehicles": [
{
"name": "Snowspeeder",
"model": "t-47 airspeeder"
},
{
"name": "Imperial Speeder Bike",
"model": "74-Z speeder bike"
}
]
}
}
}
}
If we want to do a union on different object types, we can:
query Search($name: String!) {
search(name: $name) {
... on Person {
name
birthYear
}
... on Planet {
name
climate
}
}
}
This would return different fields, depending on whether the name
was for a Person like “Luke Skywalker” or a planet like “Tatooine”.
Enabling each of these scenarios is driven by the structure of the schema.
There are a number of tools available, including Apollo Studio, Prisma, GraphiQL, and New Relic. Each of these is able to track performance and errors as needed.
Yes!
AI APIs can be used as a data source, but for using AI in the creation of queries there is GQLPT - where you can leverage AI to generate GraphQL queries from plain text.GraphQL can be a useful tool, when used in the right scenarios. Use it when working with complex data and evolving requirements, make sure you consider security as you would with any API, and it can be a powerful complement to your other existing REST APIs.