Simple GraphQL Enums
A simple way to use constants in your GraphQL and Database Schemas.
Over the past year, Hex Labs has gone all in on GraphQL. We love the strongly-typed guarantees, introspection capabilities, and granular analytics it enables.
One thing were always struggled with; however, was how to organize our enums
or known constant values efficiently for use across our application. This includes usage in our various services, GraphQL Schemas, and database validation logic.
We’ve recently come up with an organization that we think is pretty good. Let’s start with the example of enumerating Stripe Plans, which represent the various free and paid plans a user can be subscribed to on our platform. The possible values of the plans are: free
, hobby
, growth
, and enterprise
.
Project Structure & Defining Constants
Let’s image out file structure looks like this:
// Application File Structure/src
| /Constants
|-- index.js
|-- index.test.js
|---- /StripePlans
|------ index.js
|------ index.test.js
| /Enums
|-- index.js
|-- typeDefs.js
|-- typeDefs.test.js
|-- resolvers.js
|-- resolvers.test.js
| ...rest of your GraphQL Schema, Data Services, etc
Let’s start with the file StripePlans/index.js
. This file will export key-value pairs that represent the Stripe plans.
// StripePlans/index.jsmodule.exports = {
FREE: 'free',
HOBBY: 'hobby',
GROWTH: 'growth',
ENTERPRISE: 'enterprise'
}
This file is fairly simple and allows you to reference the actual plans, the values like so: StripePlans.HOBBY
.
Now, let’s take a quick look at Constants/index.js
. This file will collect and export all sub-constants in the application.
// Constants/index.jsconst StripePlans = require('./StripePlans')module.exports = {
StripePlans,
}
Fairly straightforward so far, yes?
GraphQL Enums
GraphQL enums let consumers of your API query with strongly typed constants instead of just plain strings.
Let’s take a look at our typeDefs
and resolvers
for these enums.
// Enums/typeDefs.jsimport { gql } from 'apollo-server'
import Constants from '../Constants'module.exports = gql`
enum StripePlans {
${Object.keys(Constants.StripePlans}
`
Kaboom! How easy is that? Just map over the keys of the the StripePlans from constants, and you have immediately declared FREE
, HOBBY
, GROWTH
, and ENTERPRISE
as enum values.
Now, that’s awesome, but it doesn’t map to the actual values of those keys…yet. To do that, let’s hop into our resolvers file.
// Enums/resolvers.jsimport Constants from '../Constants'module.exports = Constants
Wut. Awesome, right? Because of our clear and consistent naming conventions, we’re actually able to just use our Constants
and the resolvers
for our enums! Just plug your typeDefs
and resolvers
into you GraphQL schema and you’re good to go!
Now, when someone queries with the enum type HOBBY
as a param, you’ll actually receive the value of that enum ( hobby
) in your resolver! This is awesome because you no longer have to manually map the enum to the value using the Constants file- it’s a win-win-win.
Happy coding!
Heads up, I’m building a really neat abstraction layer on top of any database that automatically creates REST and GraphQL APIs for you. If you want early access, fill out our survey here!