In order to get data to use in our applications, we typically need to request it from an API via an endpoint that returns a dataset in a particular format, such as json or xml. We've grown so accustomed to the restful api format that it has become second nature, or simply the way that apis are supposed to work. But because we're developers and because paradigms in this industry are always changing, we will see in this blog post how GraphQL makes fetching data a more efficient and data-rich process.
So what is GraphQL? In brief, GraphQL is a query language for APIs that was designed by Facebook. The purpose of GraphQL is to prioritize getting the data that the client wants and expects. It helps solve the issue of overfetching and underfetching data. Overfetching is having to handle lots of unwanted and unnecessary data that comes from an API when we make a query while underfetching is having to fetch data from multiple endpoints in order to accrue the data we need to satisfy the client's needs. Consider the example scenario where we want an NBA player's average points scored against a certain opponent on their court. We have some relational data that we need and likely will have to hit multiple endpoints in order to get the specific data that we want, and we'll definitely get a lot of data we don't. GraphQL allows us to make smart queries we define from just one endpoint so we can reduce our calls to APIs, making our functionality both faster and cheaper, particularly at scale. Now that we know the purpose of GraphQL and the general problems it was built to solve, let's dive in to how we should approach using it.
The best place to start learning GraphQL is taking a good look at the language specification, or spec for short. A spec is a technical document that describes what a programming language is capable of and used for. It defines guidelines for designing schemas, drafting queries and other rules for using the language. As a spec we don't need to worry about what programming language is used in conjunction with GraphQL. It supports pretty much all of them. The queries themselves are an object syntax and the shape of the data returned is reflected in that. Queries can take arguments, use aliases, accept type definitions, pass variables to make queries dynamic and more. A notable quality of GraphQL is that it is a typed language. This adds specificity to queries and helps ensure data quality and predictability, leading to fewer bugs in our code. A type can be defined as anything we want from the API. Going back to our NBA player example, we could define a type as follows:
const typeDef = gql
type Player {
name: String!
avgPoints: Int!
awayGame: Boolean!
}
This type definition is a model of exactly the data we want to extract from an API call and can also be used to create queries. The gql and type keywords are GraphQL syntax, as is the capitalization of the datatypes. The exclamation mark denotes required values. Each of these type definitions would need to be exported and used in some kind of server middleware, the most popular being Apollo.
const { ApolloServer } = require('apollo-server-express');
const express = require('express');
const app = express();
const app = express();
const server = new ApolloServer({ typeDef });
server.applyMiddleware({ app });
app.listen({ port: 8001 }, () => {
console.log(listening on port 8001});
The above example is a basic setup for using an apollo server with express. We pass in the typeDef to a new instance of an apollo server that gets applied to the express server. This means that our server now has a definition for an object that we will return from an API call. This is just the small part of how to implement GraphQL, but the point stands that with it we can easily determine the shape and content of data from API requests. A point of note is that not all projects would experience the benefit of using GraphQL, but for applications that need a lot of data assembly and make a lot of API requests it can be a really powerful option.
Top comments (0)