GraphQL Session 1 - Introduction

Photo by Chandler Walters

It is a GraphQL series of 4 sessions. Below table will describe the topic discussed in every session.

Session #Description
1Introduction to GraphQL
2Setup ApolloServer and Deep dive into resolver
3Advanced topics like subscription, cacheing
4Integrating GraphQL with Frontend (React)

What is GraphQL

If we search for What is GraphQL in Google, we will often get to see

GraphQL is a strongly typed query language for APIs.

In this session I try to explain GraphQL in simple terms.

GraphQL is a structured way of making REST API calls, specific to your application. Which means every time you make an API call to get some data, you (client) have no power to choose what data you exactly need. Instead, you alter the API response to attain your needs. GraphQL is a technology that can be used everywhere a client communicates with an API.

GraphQL solves this issue by letting you choose what data exactly you need.

API (Application Programming Interface): It is a software to software connection, that enables to exchange data among each other.
REST (Representational state transfer): An architectural style for an API that uses HTTP requests to access and use data.

The name GraphQL is because it organises the data in the form of graph data structure.

# Strongly typed query language

GraphQL is a query language for APIs and not the database. GraphQL is language agnostic, meaning GraphQL is not tied specifically to any language syntax. Hence inorder to define their type system GraphQL uses its own query language name GraphQL Query Language.

1# Schema sample
2type Player {
3 name: String!
4 age: Int!
5}

In the above schema,

  1. Player is a GraphQL object type, mostly your schema will contain object types.
  2. name and age are the fields in Player type, meaning you can only access name and age in our GraphQL query.
  3. String is a built in scalar type (will be discussed later) in GraphQL, which says name field should carry only string value and ! indicates name field is not nullable. On requesting name from GraphQL service, you will always have its value.

# Scalar types

At the time of resolving our GraphQL request, every requested field in GraphQL query will contain some data. The type of data which a field should contain is determined using scalar type.

Built in scalar types in GraphQL:

  • String
  • Int
  • Float
  • Boolean
  • ID - It is used as a key for cache. It is treated as String type but non-human readable form.

# Query

You request only specific fields you need from GraphQL service, and those required fields are requested with the help of query. Every query must define its output type under type Query.

1type Query {
2 player: Player!
3}

The above type definition of a Query named player defines that it is give output of type Player when it is executed.

The resulted response from a query will contain only the fields which we specified in it. An example query requesting for a player.

1{
2 player {
3 name
4 }
5}

This query will be sent to GraphQL service and subjected to type check against the Player type defined earlier. If the type matches, then GraphQL will plug only name field and send.

1{
2 "data": {
3 "player": {
4 "name": "Sachin"
5 }
6 }
7}

# Arguments

GraphQL allows passing arguments into queries and nested queries. GraphQL arguments are similar to QUERY PARAMETERS in REST. Every argument we pass must define its associated type.

1type Query {
2 student(id: Int!): Student!
3}

if the type of argument is a complex object then we can abstract the inupt in to input type. It lets us define the type for our input arguments.

1input StudentInput {
2 id: Int!
3 team: String
4}
5
6type Query {
7 player(input: StudentInput!): Player!
8}

GraphQL lets us not only send arguments for our query but also lets us send argument for fields. This is a key feature of GraphQL which allows to alter the response in server rather doing it in browser (client) every time.

1type Player {
2 name(caps: Boolean): String!
3}

The above type defines name field which accepts caps argument of Boolean type that can later be used in resolver to send name field in uppercase if it carries true.

1{
2 player {
3 name(caps: true)
4 }
5}

# Aliases

We noted that response from GraphQL will contain resulted data under the property named similar to our query. This restricts us to get similar data in same request. In such case we can use aliases to change the property name under which we need our desired data. Alias name can be added in front of our query name.

1{
2 captain: player(role: "Captain") {
3 name
4 team
5 matches
6 }
7 viceCaptain: player(role: "Vice captain") {
8 name
9 team
10 matches
11 }
12}

This will give response like

1{
2 "captain": {
3 "name": "Virat Kohli",
4 "team": "India",
5 "matches": 254
6 },
7 "viceCaptain": {
8 "name": "KL Rahul",
9 "team": "India",
10 "matches": 179
11 }
12}

# Fragments

From the above query we noted that we duplicated same properties in two places (name, team and matches). Instead, we can keep those fields as a template and we can mention that template name whenever we need those properties rather typing them all again.

In GraphQL we have Fragments which does the same.

1{
2 captain: player(role: "Captain") {
3 ...PlayerDetails
4 }
5 viceCaptain: player(role: "Vice captain") {
6 ...PlayerDetails
7 }
8}
9
10fragment PlayerDetails on Player {
11 name
12 team
13 matches
14}

Now our query looks much lean and easy to tell that both captain and viceCaptain will carry similar data structure.

Outro

This session we are wrapping up with some knowledge about GraphQL. In the next session we setup a GraphQL project from scratch using Apollo server and discuss widely about the resolver function.

11/24/2020
All posts
Built with ❤️ and  Gatsby