GraphQL - Type System
GraphQL - Type System
Section titled “GraphQL - Type System”GraphQL’s strong type system is a cornerstone feature. It defines the capabilities of an API, ensures predictability, enables powerful developer tooling, and catches errors early. Every GraphQL service defines a set of types which completely describe the set of possible data you can query on that service.
Core Type Categories
Section titled “Core Type Categories”GraphQL types can be broadly categorized as:
- Scalar Types: Represent primitive leaf values.
- Object Types: Represent structured data with fields.
- Input Object Types: Special objects used as arguments for mutations/queries.
- Enum Types: Represent a fixed set of possible string values.
- Interface Types: Define a contract of fields that implementing Object types must include.
- Union Types: Represent a value that could be one of several Object types.
- Root Operation Types:
Query,Mutation,Subscriptiondefining API entry points.
Scalar Types
Section titled “Scalar Types”Scalars represent single, indivisible values. GraphQL comes with built-in default scalar types:
Int: A signed 32‐bit integer.Float: A signed double‐precision floating-point value.String: A UTF‐8 character sequence.Boolean:trueorfalse.ID: Represents a unique identifier, often used for fetching objects or as keys for caching. Serialized as a String, but not intended to be human-readable.
You can also define Custom Scalar Types for specific data formats (e.g., Date, JSON, UUID) if the built-in ones aren’t sufficient. This requires defining both the schema declaration and server-side logic for serialization, deserialization, and validation.
# Built-in Scalar Usagescalar Date # Custom scalar declaration
type Product { id: ID! name: String! price: Float inStock: Boolean releaseDate: Date # Using custom scalar}Object Types
Section titled “Object Types”Object types are the most common in GraphQL. They represent a collection of named fields, where each field has its own type (which could be a scalar, enum, or another object type, allowing for nesting).
# Object Type Definitiontype Student { id: ID! firstName: String! lastName: String age: Int college: College # Field linking to another Object type}Query Type
Section titled “Query Type”The Query type is a special Object type that defines all the possible entry points for read operations on your API. Every GraphQL service must have a Query type, though it might be empty.
# Query Type Definitiontype Query { greeting: String # Simple query returning a scalar students: [Student] # Query returning a list of Student objects studentById(id: ID!): Student # Query taking an argument, returning one Student}Mutation Type
Section titled “Mutation Type”Similar to Query, the Mutation type is a special Object type defining the entry points for write operations (create, update, delete).
# Mutation Type Definitioninput CreateStudentInput { # Often use Input Objects for mutation args firstName: String! collegeId: ID!}
type Mutation { createStudent(input: CreateStudentInput!): Student # Creates a student, returns the new student deleteStudent(id: ID!): Boolean # Deletes a student, returns success status}Subscription Type
Section titled “Subscription Type”The Subscription type defines entry points for establishing real-time connections with the server, allowing clients to receive updates pushed from the server when specific events occur.
# Subscription Type Definition (Conceptual)type Subscription { newNotification(userId: ID!): Notification # Subscribe to notifications for a user postUpdated(postId: ID!): Post # Subscribe to updates for a specific post}Enum Types
Section titled “Enum Types”Enumeration types restrict a field’s value to one of a predefined set of allowed string values. Useful for representing categories, statuses, etc.
# Enum Definitionenum CourseLevel { BEGINNER INTERMEDIATE ADVANCED}
type Course { id: ID! title: String! level: CourseLevel # Field using the Enum type}List Type Modifier []
Section titled “List Type Modifier []”You can declare that a field will return a list (array) of a certain type by wrapping the type in square brackets [].
# List Type Usagetype Query { studentNames: [String] # Returns a list of strings allCourses: [Course] # Returns a list of Course objects}Non-Nullable Type Modifier !
Section titled “Non-Nullable Type Modifier !”By default, any field in GraphQL can return null. To guarantee that a field will always return a value (or trigger an error if it can’t), you append an exclamation mark ! to the type. This applies to arguments as well.
# Non-Nullable Usagetype User { id: ID! # ID will never be null username: String! # Username will never be null bio: String # Bio can be null (optional)}
type Query { userById(id: ID!): User # id argument is required, return type can be null searchUsers(term: String!): [User!]! # Requires term, returns a non-null list # where each User in the list is also non-null}Understanding combinations:
String: Can be a string or null.String!: Must be a string, cannot be null.[String]: Can be a list of strings, an empty list, or null.[String]!: Must be a list of strings or an empty list, cannot be null itself. Items within the list can be null.[String!]: Can be a list of non-null strings, an empty list, or null. The list itself can be null.[String!]!: Must be a list (cannot be null), and every item within the list must be a non-null string.
Interface and Union Types (Advanced)
Section titled “Interface and Union Types (Advanced)”Interfaces: Define a set of fields that implementing Object types must adhere to. Useful for polymorphism when different types share common fields (e.g., Character interface implemented by Human and Droid).
Unions: Define a type that can resolve to one of several distinct Object types, which don’t necessarily share fields. Useful for returning mixed search results (e.g., SearchResult could be a User, Post, or Comment).
These abstract types add more flexibility for modeling complex domains and require special handling in queries (... on TypeName fragments) and resolvers (__resolveType).