Labs ICT
Pro Login

GraphQL Types

GraphQL Types

Types are the foundation of GraphQL's type system. They define the shape of your data and ensure that queries return consistent, predictable results.

GraphQL has several built-in scalar types and lets you create your own custom types.

Scalar Types

Scalar types are the primitive types that represent single values. GraphQL has five built-in scalar types:

type Example {
  id: ID!          // Unique identifier (string or int)
  name: String!    // UTF-8 string
  age: Int         // 32-bit integer
  price: Float!    // Double-precision floating-point
  isActive: Boolean! // true or false
}

The ID type is special - it's used for unique identifiers and can be serialized as either a string or an integer. The ! after a type means it's non-nullable (required).

Object Types

Object types are the most common types you'll create. They represent a collection of fields, like a User or a Post.

type User {
  id: ID!
  name: String!
  email: String!
  posts: [Post!]!
  createdAt: String!
}

type Post {
  id: ID!
  title: String!
  content: String!
  author: User!
  tags: [String!]!
}

Notice how types can reference other types. A User has posts (an array of Post), and a Post has an author (a single User). This creates a graph of connected data.

List and Non-Null Types

GraphQL lets you modify types with list and non-null modifiers:

type Example {
  required: String!           // Non-nullable string
  optional: String            // Nullable string (can be null)
  requiredList: [String!]!    // Non-nullable list of non-nullable strings
  optionalList: [String!]     // Nullable list, but items are non-nullable
  nullableItems: [String]     // Nullable list with nullable items
}

// What this means:
// String!      → Never null
// String       → Can be null
// [String!]!   → List is non-null, items are non-null
// [String!]    → List can be null, but items can't
// [String]     → Both list and items can be null

Getting these modifiers right is important for error handling and client expectations.

Input Types

When you need to pass complex data to mutations, you use input types. They're similar to object types but designed for input.

input CreateUserInput {
  name: String!
  email: String!
  age: Int
  bio: String
}

input UpdateUserInput {
  name: String
  email: String
  bio: String
}

type Mutation {
  createUser(input: CreateUserInput!): User!
  updateUser(id: ID!, input: UpdateUserInput!): User!
}

Input types keep your mutations clean and organized. Instead of having many parameters, you group related data into a single input object.

Custom Types with Enums

Enums restrict a field to a set of predefined values. They're great for fields that have a fixed set of options.

enum Role {
  ADMIN
  USER
  MODERATOR
}

enum PostStatus {
  DRAFT
  PUBLISHED
  ARCHIVED
}

type User {
  id: ID!
  name: String!
  role: Role!
}

type Post {
  id: ID!
  title: String!
  status: PostStatus!
}

Enums make your API more type-safe and self-documenting. Clients know exactly what values are valid for each field.