What is GraphQL?

GraphQL is a query language for your API, and a server-side runtime for executing queries by using a type system you define for your data. It was developed by Facebook to optimize RESTful API calls. It is an execution engine and a data query language. In simple words, GraphQL provides a complete and understandable description of the data in API and also gives clients the power to ask for exactly what they need.

GraphQL is a collection of the following:

  • Schema definition language or SDL
  • Run time environment
  • Query Language

Why GraphQL?

  • RESTful APIs follow a clear and well-structured resource-oriented approach
  • When the data gets more complex, the routes get longer. Sometimes it is not possible to fetch data with a single request

This is where GraphQL comes into the picture. Its main advantage is: Ask for what you want − and get it.

For example, let us consider a business object Actor with the attributes id, firstName, lastName, and film. Suppose the application needs to fetch only the firstName and id. If we design a REST endpoint like /api/v1/actors, it will end up fetching data for all the fields for the actor object. This means, data is over-fetched by the RESTful service. This problem can be solved by using GraphQL.

GraphQL query:

This will return values only for the actorId and film fields. The query will not fetch values for other attributes of the Actor object. The response of the query illustrated above is as shown below –

Using GraphQL we can archive the following things:

  • Get many resources in a single request
  • Describe what’s possible with a type system
  • Move faster with powerful developer tools

Architecture

There are 3 different kinds of architectures that include GraphQL server behavior.

  • GraphQL server with connected database
  • GraphQL Server as an Integration Layer
  • Hybrid approach

GraphQL Server with Connected Database

This architecture has a GraphQL Server with an integrated database and can often be used with new projects. When a query arrives at the GraphQL server, the server reads the query’s payload and fetches the required information from the database. This is called resolving the query. It then constructs the response object and returns it to the client.

This shows that the GraphQL server and the database are integrated on a single node. The client (desktop/mobile) communicates with the GraphQL server over HTTP. The server processes the request fetches data from the database and returns it to the client.

GraphQL is actually a transport-layer agnostic. This means it can potentially be used with any available network protocol. So, it is potentially possible to implement a GraphQL server based on TCP, WebSockets, etc. It doesn’t care about the database or the format that is used to store the data either use a SQL database like AWS Aurora or a NoSQL database like MongoDB.

GraphQL Server as an Integration Layer

This approach is particularly compelling for companies with legacy infrastructures and many different APIs. GraphQL can be used to unify microservices, legacy infrastructure, and third-party APIs in the existing system.

GraphQL can be used to unify these existing systems and hide their complexity behind a nice GraphQL API. This way, new client applications can be developed that simply talk to the GraphQL server to fetch the data they need. The GraphQL server is then responsible for fetching the data from the existing systems and package it up in the GraphQL response format.

In the above diagram, a GraphQL API acts as an interface between the client and the existing systems. Client applications communicate with the GraphQL server which in turn resolves the query.

Hybrid Approach

In this architecture, we can combine the above two approaches and build a GraphQL server. GraphQL server will resolve any request that is received. It will either retrieve data from a connected database or from the integrated APIs.

Application Components

  • Server-side Component
  • Client-side Component

Server-side Component

GraphQL server forms the core component on the server-side and allows to parse the queries coming from GraphQL client applications. Other server programming components include the following –

  1. Schema – A GraphQL schema is at the center of any GraphQL server implementation and describes the functionality available to the clients which connect to it.
  2. Query – A GraphQL query is the client application request to retrieve data from a database or legacy APIs.
  3. Resolver – Resolvers provide the instructions for turning a GraphQL operation into data. They resolve the query to data by defining resolver functions.

Client-side Component

  1. GraphiQL – Browser-based interface for editing and testing GraphQL queries and mutations
  2. ApolloClient – The best tool to build GraphQL client applications. Integrates well with all javascript front-end.

Type System

GraphQL is a strongly typed language. The type system helps to define the schema, which is a contract between client and server. The commonly used GraphQL data types are as follows –

  • Scalar – Scalar types are primitive data types that can store only a single value. The default scalar types that GraphQL offers are –
  1. Int− Signed 32-bit Integer
  2. Float− Signed double-precision floating-point value
  3. String− UTF – 8-character sequence
  4. Boolean− True or false
  5. ID− A unique identifier, often used as a unique identifier to fetch an object or as the key for a cache

Syntax-

field: data_type

Code-snippet: title: String

  • Query – Entry point type to other specific types. The object type is the most common type used in a schema and represents a group of fields. An object type is composed of multiple scalar types or object types.

Syntax-

type object_type_name

{

   field1: data_type

   field2:data_type

   ….

   fieldn:data_type

}

Code-snippet:

–Define an object type–

type Book {

  isn: String

  title: String

  publisher: String

  authors: [String]

  publishedDate: String

}

–Defining a GraphQL schema–

type Query

{

   stud_details:[Student]

}

  • Mutation – The entry point for data manipulation which means Mutations are operations sent to the server to create, update or delete These are analogous to the PUT, POST, PATCH and DELETE verbs to call REST-based APIs.

Syntax:

type Mutation {

   field1: data_type

   field2(param1:data_type,param2:data_type,…paramN:data_type):data_type

}

Code-snippet:

type Mutation {

   addStudent( firstName : String, lastName : String) :Student

}

  • Enum – Useful in a situation where you need the user to pick from a prescribed list of options.

Syntax:

type enum_name{

   value1

   value2

}

Code-snippet:

type Days_Of_Week{

   SUNDAY

   MONDAY

   TUESDAY

   WEDNESDAY

   THURSDAY

   FRIDAY

   SATURDAY

}

  • List Type: It can be used to represent an array of values of a specific type. Lists are defined with a type modifier [] that wraps object types, scalars, and enums.

Syntax:

field:[data_type]

Code-snippet:

type Query{

todos: [String]

}

  • Non-nullable Type: Types can either return a value of the specified type or they can have no value.

Syntax:

field:data_type!

Code-snippet:

type Student {

   stud_id:ID!

   firstName:String

   lastName:String

   fullName:String

   college:College

}

Conclusion

GraphQL provides a standard lingo to define and consume APIs. Such standardization helps in improving the efficiency and effectiveness of interoperability of systems, applications, and/or components.