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:
| Type | Description | Example |
|---|---|---|
Int | Signed 32-bit integer | 42 |
Float | Signed double-precision floating-point | 3.14 |
String | UTF-8 character sequence | "Hello" |
Boolean | true or false | true |
ID | Unique 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
| Notation | Meaning |
|---|---|
[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!