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 |
---|---|
1 | Introduction to GraphQL |
2 | Setup ApolloServer and Deep dive into resolver |
3 | Advanced topics like subscription, cacheing |
4 | Integrating GraphQL with Frontend (React) |
What is GraphQL
If we search for What is GraphQL in Google, we will often get to see
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.
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 sample2type Player {3 name: String!4 age: Int!5}
In the above schema,
Player
is a GraphQL object type, mostly your schema will contain object types.name
andage
are the fields inPlayer
type, meaning you can only accessname
andage
in our GraphQL query.String
is a built in scalar type (will be discussed later) in GraphQL, which saysname
field should carry only string value and!
indicatesname
field is not nullable. On requestingname
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 asString
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 name4 }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: String4}56type 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 name4 team5 matches6 }7 viceCaptain: player(role: "Vice captain") {8 name9 team10 matches11 }12}
This will give response like
1{2 "captain": {3 "name": "Virat Kohli",4 "team": "India",5 "matches": 2546 },7 "viceCaptain": {8 "name": "KL Rahul",9 "team": "India",10 "matches": 17911 }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 ...PlayerDetails4 }5 viceCaptain: player(role: "Vice captain") {6 ...PlayerDetails7 }8}910fragment PlayerDetails on Player {11 name12 team13 matches14}
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.