Core Concepts

Created : August 07, 2020

Learned from How to GraphQL official tutorial.

The Schema Definition Language (SDL)

= The syntax for writing schemas

type Person {
  name: String!
  age: Int!
  posts: [Post!]!          # array of posts = one-to-many relationship
}

type Post {
  title: String!
  author: Person!
}
  • Type Person has two fields = name, age

    • ! after type = field is required.

Fetching data with queries

  • GraphQL APIs typically only expose a single endpoint.

    • This works because the returned structure of the data is not fixed.
    • It’s completely flexible and lets the client decide what data is actually needed.
  • The client needs to send more information to the server to express its data needs.

    • = this information is called a query.

Basic queries

{
  allPersons {
    name
  }
}

# return a list of all persons
{
  "allPersons": [
    { "name": "Johnny" },        # each person only has the 'name'
    { "name": "Sarah" },
    { "name": "Alice" }
  ]
}
  • allPersons = root field of the query

    • Everything inside the root field = payload of the query
# allow nested query
{
  allPersons {
    name
    age
    posts {
      title
    }
  }
}

Queries with arguments

Each field can have zero or more arguments if that’s specified in the schema.

{
  allPersons(last: 2) {
    name
  }
}

Writing data with mutations

  • Changes to the data are made using mutations.
  • 3 kinds of mutations

    • Creating new data
    • Updating existing data
    • Deleting existing data
  • Always need to start with the mutation keyword.
mutation {
  createPerson(name: "Bob", age: 36) {
    name         # specify a payload to retrieve new data
    age
  }
}

# response
"createPerson": {
  "name": "Bob",
  "age": 36,
}

GraphQL types have unique IDs that are generated by the server when new objects are created.

# Add an id like this
type Person {
  id: ID!
  name: String!
  age: Int!
}

# Directly ask for the id in the payload of the mutation
mutation {
  createPerson(name: "Alice", age: 36) {
    id
  }
}

Realtime updates with subscriptions

Subscriptions : A realtime connection to the server to get immediately informed about important events.

  • When a client subscribes to an event,

    • It will initiate and hold a steady connection to the server.
    • Whenever that particular event then actually happens, the server pushes the corresponding data to the client.
    • Subscriptions represent a stream of data sent over to the client, unlike queries and mutations that follow a typical 'request-response-cycle'.
subscription {
  newPerson {
    name
    age
  }
}
  • A connection is opened between them after a client sent this subscription to a server.
  • Then, whenever a new mutation is performed that creates a new Person, the server sends the information about this person over to the client like below.
{
  "newPerson": {
    "name": "Jane",
    "age": 23
  }
}

Defining a schema

  • Schema : Specifies the capabilities of the API and defines how clients can request the data.

    • A contract between the server and client.
    • Simply a collection of GraphQL types.
  • Special root types : Entry points for the requests sent by the client.

    • type Query { ... }
    • type Mutation { ... }
    • type Subscription { ... }
    • inside root types : allPersons, createPerson, newPerson are root fields
    • Root fields define the available API operations
  • To enable the query allPersons with last argument
type Query {
  allPersons(last: Int): [Person!]!
}
  • To enable the mutation createPerson with name, age arguments
type Mutation {
  createPerson(name: String!, age: Int!): Person!
}
  • To enable the subscription newPerson
type Subscription {
  newPerson: Person!
}