Enums
Enums are great. In TypeScript, I like using Sean Nicolay’s Flow-inspired enum library, with UPPER_SNAKE keys and values:
import { Enum, EnumValue } from "@kejistan/enum";
const MyStringEnum = Enum({
VALUE_ONE: "VALUE_ONE",
VALUE_TWO: "VALUE_TWO",
});
type MyStringEnum = EnumValue<typeof MyStringEnum>;
Why UPPER_SNAKE?
We want consistency across backend code, frontend code, API definitions, and persistence.
GraphQL spec recommends it:
Google JSON API recommends it:
These REST APIs recommend it:
Protobuf generated code uses it:
- https://developers.google.com/protocol-buffers/docs/proto3#enum
- https://developers.google.com/protocol-buffers/docs/reference/java-generated#enum
Persistence
I’ve tended to persist enums in TEXT-type columns instead of integers for data readability as outlined here:
Prisma enums are another option:
https://www.prisma.io/docs/concepts/components/prisma-schema/data-model#defining-enums
In some cases, I like having enums in the database and referencing them by qid. Example with three tables:
user
- a userrole
- a role (with a label likeCUSTOMER_ADMIN
,CORP_ADMIN
, etc)user_role
- join table between users and role
This makes it easy to rename a role from say TENANT_ADMIN
to CUSTOMER_ADMIN
. Only the “label” column with the role table needs to be updated. This approach also allows for UI to be built for end users to add/remove options without relying on code changes.