Episode 4 of 9

Schema & Types

Deep dive into the GraphQL type system — scalar types, object types, enums, and the schema definition.

Schema & Types in GraphQL

The schema is the heart of every GraphQL API. It defines what data can be queried, what types of data exist, and the relationships between them. Let's dive deep into the GraphQL type system.

The Schema Definition Language (SDL)

GraphQL schemas are written in SDL (Schema Definition Language). Here's a complete example:

type Game {
  id: ID!
  title: String!
  platform: [String!]!
  reviews: [Review!]
}

type Review {
  id: ID!
  rating: Int!
  content: String!
  game: Game!
  author: Author!
}

type Author {
  id: ID!
  name: String!
  verified: Boolean!
  reviews: [Review!]
}

type Query {
  games: [Game]
  game(id: ID!): Game
  reviews: [Review]
  review(id: ID!): Review
  authors: [Author]
  author(id: ID!): Author
}

Scalar Types

GraphQL has five built-in scalar types:

TypeDescriptionExample
IntSigned 32-bit integer42
FloatSigned double-precision floating-point3.14
StringUTF-8 character sequence"Hello"
Booleantrue or falsetrue
IDUnique identifier (serialized as String)"abc123"

Non-Nullable Types (!)

By default, any field can return null. Adding ! makes it required:

type Game {
  id: ID!            # Required — can never be null
  title: String!     # Required
  platform: [String!]! # Required list of required strings
  description: String  # Optional — can be null
}

Understanding List Notation

NotationMeaning
[String]Nullable list of nullable strings
[String!]Nullable list of non-null strings
[String!]!Non-null list of non-null strings
[String]!Non-null list of nullable strings

Object Types

Object types represent the entities in your API. They can reference other object types to create relationships:

type Review {
  id: ID!
  rating: Int!
  content: String!
  game: Game!       # Relationship to Game type
  author: Author!   # Relationship to Author type
}

Enum Types

Enums define a set of allowed values:

enum Platform {
  PC
  PS5
  XBOX
  SWITCH
  MOBILE
}

type Game {
  id: ID!
  title: String!
  platform: [Platform!]!
}

The Query Type

The Query type is special — it defines all the entry points for reading data:

type Query {
  games: [Game]              # Get all games
  game(id: ID!): Game        # Get a single game by ID
  reviews: [Review]          # Get all reviews
  authors: [Author]          # Get all authors
}

The Mutation Type

Similarly, the Mutation type defines entry points for modifying data (we'll cover this in detail later):

type Mutation {
  addGame(game: AddGameInput!): Game
  deleteGame(id: ID!): [Game]
}

Input Types

Input types are used for mutation arguments:

input AddGameInput {
  title: String!
  platform: [String!]!
}

Complete Schema Example

Let's update our server's schema:

const typeDefs = `#graphql
  type Game {
    id: ID!
    title: String!
    platform: [String!]!
    reviews: [Review!]
  }

  type Review {
    id: ID!
    rating: Int!
    content: String!
    game: Game!
    author: Author!
  }

  type Author {
    id: ID!
    name: String!
    verified: Boolean!
    reviews: [Review!]
  }

  type Query {
    games: [Game]
    game(id: ID!): Game
    reviews: [Review]
    review(id: ID!): Review
    authors: [Author]
    author(id: ID!): Author
  }
`;

Key Takeaways

  • The schema defines your entire API using SDL
  • There are 5 scalar types: Int, Float, String, Boolean, ID
  • ! makes fields non-nullable (required)
  • Object types can reference each other to create relationships
  • The Query type defines read operations, Mutation defines write operations

Next episode: Resolver Functions — where we bring the schema to life with actual data!