GraphQL
on their website
Developed by Facebook in 2012
for their Mobile Apps
Open sourced first spec 2015
Graphql.js
Its a Query Language built on top of REST
but way better
Everything is a single POST call /endpoint
Query is sent as post body
query {
users {
name
}
likes {
id
}
}
Sample Call
curl 'http://localhost/graphql?' \
-XPOST \
--data-binary 'query { users: { name } likes: { id } }'
query {
users {
name
bio
pic
likes: {
id
}
}
}
Sample Call
Use Case 1
Just Make Another Call
GET /users
GET /likes/1
GET /likes/2
GET /likes/3
No of Calls: 4
REST
3
Prathik
4
Saurabh
5
Armaan
When user list and likes are separate calls
query {
users {
name
profilepic
bio
likes: {
id
}
}
}
No of Calls: 1
GraphQL
3
Prathik
4
Saurabh
5
Armaan
Use Case 2
Just Rename That Field
[{
name
profilepic
bio
}]
[{
name
pic
bio
}]
Code Change Everywhere
REST
When API renames a field
query {
users: {
name
profilepic: pic
bio
}
}
No Code Change
GraphQL
Use Case 3
Just Play Around
Its takes time to write documentation
REST
Its painful to keep it up to date
REST
Its tough to agree on one tool
Provides documentation free of cost
GraphQL
Swagger, Postman, GitBook all in one
GraphQL
Use Case 4
I Don't Need That
REST
GET /users
GET /users-without-pic
or
GET /users?includepic=false
Prathik
3
Saurabh
4
Armaan
33
Loki
300
3
Prathik
4
Saurabh
When you want to skip a field
query {
users: {
name
bio
pic
likes: {
id
}
}
}
GraphQL
query {
users: {
name
likes: {
id
}
}
}
Prathik
3
Saurabh
4
Armaan
33
Loki
300
3
Prathik
4
Saurabh
Client needs to understand single auth mechanism
Plus all advantages of single endpoint
Basics
Schema
Server Side
Three basic things
Query
Mutation
Subscription
Query
type query {
users: [User]
user(id: Int!): User
}
Types
id: ID
name: String
age: Int
isHuman: Boolean
amount: Float
Scalar
enum Gender {
MALE
FEMALE
OTHER
}
Enum
location: [Location]
Lists
gender: Gender
Type User {
id: ID
name: String
}
Object
age: Int!
location: [Location!]!
Not Null
users(name: String): [User]
user(id: Int!): User
inteface Message {
id: Int!
msg: String!
}
type SMS implements Message {
id: Int!
msg: String!
}
Interfaces
type Mutation {
createMsg(input: string): Message
updateMsg(id: ID!, input: string): Message
}
Mutation
Fetching Data
Client Side
query {
users {
name
}
likes {
id
}
}
Recall: Sample Call
curl 'http://localhost/graphql?' \
-XPOST \
--data-binary 'query { users: { name } likes: { id } }'
Query
users {
name
age
}
{
data: {
users: [
{
name: 'Prathik'
age: 7
}, {
name: 'Saurabh'
age: 7
}, {
name: 'Armaan'
age: 7
}
]
}
}
Query
users {
name
age
}
query {
users {
name
age
}
}
Arguments & Variables
user(id: 7) {
name
age
}
query Query1($id: Int) {
users(id: $id) {
name
age
}
}
{
id: 7
}
Fragments
user {
...userFragment
}
likes {
id
user: {
...userfragment
}
}
fragment userfragment on User {
name
id
}
Alias
user {
id
username: name
}
organiser: user(id: 7) {
name
id
}
admin: user(id: 8) {
name
id
}
mutation
mutation Query1($user: User) {
createUser(user: $user) {
id
}
}
{
user {
name
bio
}
}
Code
Demo
Gotchas 1
Inception
type Query {
likes
users
}
type Likes {
id
user: User
}
type Users {
name
pic
bio
likes: [Likes]
}
query {
users {
name
likes {
id,
user {
name,
likes {
id,
user {
id
}
}
}
}
}
Schema
Client Query
Its like query inside query inside query
Design your custom Query Complexity Rule
Example: Every { = 5 point Every Page = 10 points Every Nesting = 15 points Max Allowed = 60 points
Solution
Gotchas 2
Problem Transferred
GET /users
GET /likes/1
GET /likes/2
GET /likes/3
REST
N + 1
query {
users: {
name
likes: {
id
}
}
}
GraphQL
N + 1
1
Database still collapses
Use a Query batcher
N + 1
1 + 1
Solution
Gotchas 3
Overwhelmed
Traditional Rate Limiting not suitable
REST
Max RPS = 2000
Rate limiting is server's job not of GraphQL
Use a combination of
Rate Limiting & Query Complexity (QC)
REST
Max RPS = 2000
GraphQL
Max RPS = 500
Max QC = 60
Solution
Links
Namaste
Thank You
GraphQL
By Prathik S
GraphQL
- 459