[GraphQL] Basics

Benefits of GraphQL

  1. Avoid over-fetching and under-fetching
  2. Reduce payload, increase efficiency
  3. Strongly typed, use Schema

The Schema Definiation Language (SDL)

Defining simple types (! represents not null)

1
2
3
4
5
6
7
8
type Person {
name: String!
age: Int!
}

type Post {
title: String!
}

Adding a relation

1
2
3
4
5
6
7
8
9
10
type Person {
name: String!
age: Int!
posts: [Post!]!
}

type Post {
title: String!
author: Person!
}
1
2
3
4
5
{
allPersons {
name
}
}

Will return

1
2
3
4
5
6
7
{
"allPersons": [
{ "name": "Johnny" },
{ "name": "Sarah" },
{ "name": "Adam" },
]
}
1
2
3
4
5
6
{
allPersons(last: 2) {
name
age
}
}

Will return

1
2
3
4
5
6
{
"allPersons": [
{ "name": "Johnny", age: 10 },
{ "name": "Sarah", age: 2 },
]
}
1
2
3
4
5
6
7
8
{
allPersons {
name
posts {
title
}
}
}

Will return

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
"allPersons": [
{
"name": "Johnny",
"posts": [
{ "title": "GraphQL" },
]
},
{
"name": "Sarah",
"posts": [
{ "title": "Another title" },
]
},
]
}

Mutations

3 kinds of mutations:

  • Creating new data
  • Updating existing data
  • Deleting existing data
1
2
3
4
5
6
7
8
9
10
11
12
13
14
mutation {
createPerson(name: "Bob", age: 36) {
name
age
}
}

// Subscribe to the response from the server, push the created data back to the client
subscription {
createPerson(name: "Bob", age: 36) {
name
age
}
}

The GraphQL Schema

  • Defines capabilities of the API by specifying how a client fetch and update data
  • Represents contract between client and server
  • Collection of GraphQL types with special root types

Root types

Defines the entry point of query.

1
2
3
4
5
6
7
8
9
10
11
type Query {
...
}

type Mutation {
...
}

type Subscription {
...
}

Example:

To enable:

1
2
3
4
5
{
allPersons {
name
}
}

We’ll need Schema:

1
2
3
type Query {
allPersons(last: Int): [Person!]!
}

1
2
3
4
5
mutation {
createPerson(name: "Bob", age: 36) {
id
}
}
1
2
3
type Mutation {
createPerson(name: String!, age: String!): Person!
}
1
2
3
4
5
6
subscription {
newPerson {
name
age
}
}
1
2
3
type Subscription {
newPerson: Person!
}

More CRUD to the Schema

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
type Person {
id: ID!
name: String!
age: Int!
posts: [Post!]!
}

type Post {
id: ID!
title: String!
author: Person!
}

type Query {
allPersons(last: Int): [Person!]!
allPosts(last: Int): [Post!]!
}

type Mutation {
createPerson(name: String!, age: String!): Person!
updatePerson(id: ID!, name: String!, age: String!): Person!
deletePerson(id: ID!): Person!

createPost(title: String!): Post!
updatePost(id: ID!, title: String!): Post!
deletePost(id: ID!): Post!
}

type Subscription {
newPerson: Person!
updatedPerson: Person!
deletedPerson: Person!

newPost: Post!
updatePost: Post!
deletedPost: Post!
}