Enums (short for Enumerations) in GraphQL are a special kind of scalar that is restricted to a particular set of allowed values. They are useful for representing a fixed set of options, such as the days of the week, user roles, or status codes.

Key Concepts

  1. Definition: Enums are defined in the GraphQL schema using the enum keyword.
  2. Usage: Enums can be used as the type for fields, arguments, and input types.
  3. Validation: GraphQL ensures that only the defined values are used, providing a layer of validation.

Defining Enums

Enums are defined in the schema with the enum keyword followed by the name of the enum and the set of allowed values.

enum Role {
  ADMIN
  USER
  GUEST
}

In this example, Role is an enum with three possible values: ADMIN, USER, and GUEST.

Using Enums in Schemas

Enums can be used in various parts of the schema, such as in object types, input types, and arguments.

Example: Using Enums in Object Types

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

Here, the role field in the User type is of type Role, meaning it can only have one of the values defined in the Role enum.

Example: Using Enums in Input Types

input CreateUserInput {
  name: String!
  role: Role!
}

type Mutation {
  createUser(input: CreateUserInput!): User
}

In this example, the CreateUserInput input type uses the Role enum for the role field. This ensures that when creating a user, the role must be one of the allowed values.

Practical Example

Let's create a simple GraphQL schema that includes an enum for user roles and a mutation to create a user.

Schema Definition

enum Role {
  ADMIN
  USER
  GUEST
}

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

input CreateUserInput {
  name: String!
  role: Role!
}

type Mutation {
  createUser(input: CreateUserInput!): User
}

type Query {
  users: [User]
}

Resolver Implementation

const { ApolloServer, gql } = require('apollo-server');

const typeDefs = gql`
  enum Role {
    ADMIN
    USER
    GUEST
  }

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

  input CreateUserInput {
    name: String!
    role: Role!
  }

  type Mutation {
    createUser(input: CreateUserInput!): User
  }

  type Query {
    users: [User]
  }
`;

let users = [];
let idCounter = 1;

const resolvers = {
  Query: {
    users: () => users,
  },
  Mutation: {
    createUser: (_, { input }) => {
      const user = { id: idCounter++, ...input };
      users.push(user);
      return user;
    },
  },
};

const server = new ApolloServer({ typeDefs, resolvers });

server.listen().then(({ url }) => {
  console.log(`🚀 Server ready at ${url}`);
});

Explanation

  • Schema Definition: We define an enum Role with three values: ADMIN, USER, and GUEST. The User type has a role field of type Role. The CreateUserInput input type also uses the Role enum for the role field.
  • Resolvers: We implement a simple resolver for the createUser mutation that adds a new user to the users array. The role field is validated against the Role enum.

Exercises

Exercise 1: Add a New Enum

  1. Define a new enum Status with values ACTIVE, INACTIVE, and BANNED.
  2. Add a status field to the User type using the Status enum.
  3. Update the CreateUserInput input type to include the status field.

Solution

enum Status {
  ACTIVE
  INACTIVE
  BANNED
}

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

input CreateUserInput {
  name: String!
  role: Role!
  status: Status!
}

type Mutation {
  createUser(input: CreateUserInput!): User
}

type Query {
  users: [User]
}

Exercise 2: Implement the Resolver

  1. Update the resolver for the createUser mutation to handle the new status field.

Solution

const resolvers = {
  Query: {
    users: () => users,
  },
  Mutation: {
    createUser: (_, { input }) => {
      const user = { id: idCounter++, ...input };
      users.push(user);
      return user;
    },
  },
};

Common Mistakes

  1. Using Undefined Enum Values: Ensure that only the values defined in the enum are used. GraphQL will throw an error if an undefined value is used.
  2. Case Sensitivity: Enum values are case-sensitive. ADMIN and admin are considered different values.

Conclusion

Enums in GraphQL provide a way to define a set of allowed values for a field, ensuring data consistency and validation. They are easy to define and use in your schema, making them a powerful tool for creating robust APIs. In the next module, we will explore more advanced schema design concepts, such as interfaces and unions.

© Copyright 2024. All rights reserved