Problem:
We want a user to have one of two possible roles: BASIC
or PREMIUM
.
Currently, a client could potentially set the role of the user to any arbitrary string, like CHICKEN
, which would obviously not make sense in our app.
We need a mechanism to establish a contract that the user.role can only be set to a pre-approved value.
Solution:
Enums
Enums are a way to create a list of pre-approved values for a certain type. In our case, we want to define an enum named Role
that contains two possible values: BASIC
and PREMIUM
.
This mechanism tells our program that a Role
type can only ever have the value BASIC
or PREMIUM
.
Implementation:
How to use enums to improve our role-based permission system
Step 1
Define the Role
enum in the top level of the schema.
import { gql } from "apollo-server-express"; | |
import userSchema from "./user"; | |
import postSchema from "./post"; | |
import commentSchema from "./comment"; | |
const linkSchema = gql` | |
scalar Date | |
enum Role { | |
BASIC | |
PREMIUM | |
} | |
type Query { | |
_: Boolean | |
} | |
type Mutation { | |
_: Boolean | |
} | |
type Subscription { | |
_: Boolean | |
} | |
`; | |
export default [linkSchema, userSchema, postSchema, commentSchema]; |
Step 2
Specify the Role
enum as the return type for the role
field on the User
type (in schema/user.js).
export default gql` | |
extend type Query { | |
... | |
} | |
extend type Mutation { | |
... | |
} | |
type User { | |
id: ID! | |
username: String! | |
email: String! | |
posts: [Post!] | |
role: Role! # our new Role type | |
} | |
`; |
Step 3
Use the Role
enum as the argument type for our updateRole
mutation:
import { gql } from "apollo-server-express"; | |
export default gql` | |
extend type Query { | |
... | |
} | |
extend type Mutation { | |
... | |
updateRole(newRole: Role!): User! # enum as argument | |
} | |
type User { | |
id: ID! | |
username: String! | |
email: String! | |
posts: [Post!]! | |
role: Role! | |
} | |
`; |
This has the added benefit of giving us autocomplete in GraphQL Playground when setting the user’s role with this mutation:
Sweet! Less room for error.