Introduction to GraphQL

Query Language for APIs & Backend | An alternative to REST API

Inspiration for GraphQL

Y’all as developers, should be familiar with client-server architecture in software and usage of REST concepts there to build server APIs. There will be variety of endpoints to handle, and some maybe quite redundant. Thereby REST API might turn out hard to maintain in the end.

Query & Its Response. Img Src: medium.com

GraphQL here tries reduce these complexities by arranging back-end data in graphical view. Then client can query any fragment of this data, passing their query & get only what’s required.

Here’s some example:

Moreover when loading complex web application, we tend to make multiple REST calls to fetch required data, taking more network usage and handling complexities in asynchronous response. As an example:

REST_API_URL/authors --> GET all authors
REST_API_URL/posts --> GET all posts
REST_API_URL/author/12 --> GET all details of authorId: 12

But in GraphQL you could just make one query and get all required data:

{
authors {
name
},
posts {
content
},
getAuthor(id: 12){
name,
email
}
}

Comparison with REST

GraphQL is also known to be trending alternative for REST concepts & APIs. The following example tries to identify simple problem with REST endpoints and how GraphQL can be used to mitigate these challenges.

Suppose there’s mobile and web applications using same REST API. So if there’s endpoint fetch movie details using: ‘/movies’ giving all the information about movies such as title, genre, year, director and such. In web application all data fetched using this endpoint will be used, but in mobile application only title and year is required.

REST_API_URL/movies --> Movies with title, genre, year, directorWEB APPLICATION --> Use all attributes: title, genre, year, director
MOBILE APPLICATION --> Only need title, year

But if mobile application is also using ‘/movies’, it’ll be waste to fetch all those unused data. On the other hand if we’re to make simple endpoint for mobile such as: ‘/movies/mobile’, it’ll be more additional work & waste. If here’s the case there should be new endpoint called /movies/mobile or within /movies route, there need to be verification of mobile devices. So thereby it is understood that traditional REST APIs doesn’t provide customized response data, and all of it has to be handled by server.

But here we transfer responsibility to client, where we could specifically ask for what’s needed and will reduce information flowed through network.

What is GraphQL?

I guess you’ll are kind of clear about GraphQL from above example, but let us get it some definitions to clear up the air.

A Query Language for your API → Simply Flexible API layer

All of the data you need in one request

It was designed by Facebook, and now open sourced. As the name suggests it organizes data in graphical way, and data is taken by queries and not by end points. (Thereby regarded as an alternative to REST too.) But note that GraphQL is not actually graph database like Neo4j.

Typical GraphQL structure consists of two elements.

1. GraphQL Server:

Server component of GraphQL organize data sources to kind of in tree structure. Data sources could be variety of existing technologies such as databases, microservices, REST API & SOA. These servers could be written in variety of languages such as JavaScript, C#, Java, GO and most common projects are by graphql.org, apollo-server and find others here: Servers

Image Src: medium.com

2. GraphQL Client:

After server builds up data in graphical view, client should query to get data. This will add more weight on to client, but client can request exact data required for its operations without over fetching or under fetching. Famous client projects include: apollo-client and relay. (relay is famous in react ecosystem, and even regarded as alternative to redux for state management.)

Why GraphQL?

With these insights, lets wrap it up why GraphQL was needed.

  • Regarded as alternative to REST since dilemmas with multiple endpoints is tackled here. Here single versatile query system is made instead of complex APIs.
  • All of the data is arranged in graphical view, and accessing & mutating data in done according to client. (Thereby moving control there.) Another main advantage is only required data will be fetched.
  • Another major advantage of GraphQL is that you could request all needed data for UI view, rather than making multiple REST API calls.

Lets build one!

Img Src: grahql.com

Here’s brief overview of GraphQL system:

GraphQL stands in middle of clients and data sources. And kind of wrapping data sources into required format.

Building the GraphQL Server

Lets just get started with basic blocks of building GraphQL server, how data is arranged in GraphQL format, and how data sources are configured. For this brief setup, we’ll be using apollo-server, but these concept remains the same for any implementation.

  • Install graphql components.

Here we’ll be using NodeJS implementation of GraphQL.

npm install --save apollo-server graphql// apollo-server-express can be used for GraphQL together with REST.
  • Building the schema

In order to organize data, we’ll be creating GraphQL schema. This is the format data is to be stored and accessed (queried). Here its is defined as typeDefs.

Here schema typically consists of type Query which is the format queries come in. Moreover there could be other data models required and defined by type.

Here Query of book would return model of Book type. That model consists of title, author.

When query is received, server should know what data to send. This done in revolvers, and here its just returning hard coded value. Typically this could be data from database, REST API.

Note Schema Definition Language is encouraged to follow for advanced setup. And these schema can also be defined using graphql module as well by, const { GraphQLSchema, GraphQLObjectType } from 'graphql'.

  • Testing your server

In order to check above server and its queries, we can use in-browser IDE integrations called GraphQL Playground and graphiql. Just navigate localhost:4000 & run new query named: book.

  • Connecting data sources

In real world context, there’s no point in returning hard coded values from GraphQL servers. Thereby it is evident that data sources should be configured, and what GraphQL server does it arrange data in correct format for queries & mutations.

In this example we’ll consider how to resolver change when connecting MongoDB database via mongoose. Note that node,mongodb configurations are not covered here, and only graphql integration is covered here.

// Queries and Mutations finally end up as mongodb operationsconst resolvers = {
Query: {
getPosts: () => {
Post.find({}, (err,data) => data );
},
getPostById: (obj, args, context, info) => {
Post.findOne({id: args.id}).then((post) => post);
}
},

Mutation: {
addPost: (obj, args) => {
posts.push({id: args.id, content: args.content});
posts.save(done);
}
}
};

This just covers MongoDB integration to resolve graphql fields. However it could be resolved by databases, microservices, existing REST APIs and such.

// Adding data sources to server, it could be used everywhere!
const server = new ApolloServer({
typeDefs,
resolvers,
dataSources: () => ({
launchAPI: new LaunchAPI(),
userAPI: new UserAPI({ store }),
}),
context: () => {
return { token: 'API-TOKEN' };
},
});

But for the ease of the tutorial, we will be keep dealing with code data.

Building the GraphQL Client

After we set up GraphQL server, and data is available in desired format, we should be able to view & manipulate its data via clients. As mentioned above according to your application language, our GraphQL client changes, and list of those could be find here: GraphQL Clients.

As we’re not building client application, we’ll be using above mentioned sample client Playground, to get an idea about client operations.

  • What are queries, mutations and other useful types!

There two primary requirements for clients: data fetching (queries) and data manipulation (mutations).

Queries: As seen above queries are quite simple to fetch data, and you can request exactly what you need.

# Used to query book and expects only title of it, not the author.
query {
book {
title
}
}
# Note: That this query have to available in server.
query {
findBookByAuthor(name: "Trevor Noah") { # Pass argument to query.
title # Get only title.
}
}

Mutations: There we’re trying to update state of the data. This should be defined in schema of the server as well.

Here mutation is defined by addPost with type Mutation. It expects non-empty Strings as title and content, and then returns array of Post.

When we check resolve method for this mutation we could see that arguments are accessed, and necessary operations are performed.

As per this example we’ll be just pushing new post in to array and return entire array of Posts. But in real scenarios, it would be to update underlining databases or make service call or such.

This operation can be verified as below:

Subscriptions: Another useful type is related to subscriptions of events from server. This is usually associated with WebSockets, but implementations can be seen from Prisma.io too. However will be not going into depth here.

type Subscription {
newPost: Post
}

Fragments: When you want to fetch only part of complicated nested structure, fragments can be used to query better.

  • Using in client applications

Even though we executed most of queries and mutations in in-browser graphql tool, it should be noted that these are actually called from clients. Most notable client libraries include, apollo-client and relay.

Img Src: medium.com

Here little example how this is used in react client application:

As mentioned above, GraphQL can be used extract what is absolutely necessary. Thereby according to client application requirement, we can restrict what we are fetching from the backend. As an example, if mobile application doesn’t show photos, it could omit from getting thumbnail links of user list.

Moreover as you know react has now become de facto choice when building web application, and state management is vital part of those application. Graphql related client package called relay have gained much attention for state management, and even considered worthy competitor to redux.

If you want to try with some other packages when building GraphQL:

On above example we were using apollo based packages, but here graphql is used. You’ll find that all the concepts remains the same here too.

In browser navigate to localhost:4000/graphql and execute this:

mutation {
createMessage(input: {
author: "andy",
content: "what up?",
}) {
id
}
}

This will prompt graphiql in-browser tool, which is quite similar to what we used before.

Obj resolvement in GraphQL:

query {
getAuthor(id: 5){
posts { title}
}
}

In this kind of nested queries, it will be resolved from higher to lower. So getAuthor() would return Author typed object. It will be passed to next inner query. So here posts query will be resolved by returned Author, and it will act as obj for this inner query.

I believe that you’ll have gained brief introduction in GraphQL, and how it challenges traditional REST concepts. Hope this will be helpful to get started with GraphQL, and any suggestions, feedback are always appreciated.

Just to wrap it up here’s GraphQL integration into development ecosystem:

Img Src: apollographql.com

Resources

https://graphql.org/learn/

https://www.howtographql.com

https://www.apollographql.com/docs

Full Stack Developer | BiBi

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store