go back

Placeholder for post cover image
Cover image for post

Salvaging GraphQL Enums from BE for FE ⚓️

August 28, 2020

Leveraging introspection queries to fetch enum constants defined in a back-end (BE) Graph API to use in corresponding front-end (FE) interfaces.

For smaller & monolithic projects, it's easy to have GraphQL types defined in a shared folder that both can reference. But the FE & BE for a project I'm currently working are isolated microservices & live in separate repositories.

Enums live at the service layer as they are tightly coupled to the types they define. But there are instances where the client also needs to know these enums (like a dropdown of discrete values).


There are many ways to go about getting these to the FE:

For the sake of metaphor I'm using the salvage/treasure example, but that's not to say the BE is dead or broken! It's very much the opposite, I just like the metaphor so sticking with it. 😁

shipwreck

Defining enums on BE 🔩

I won't go deep into this, but let's assume you have a graph service with a schema that has an enum defined like so:

enum TreasureTypeEnum {
    GOLD_DOUBLOON,
    SILVER_COIN,
    EMERALD_RING
}
Enter fullscreen mode Exit fullscreen mode

Fetching on FE 🤿

An introspection query is magical; it primarily returns the queries an API supports, but diving further it can provide supported enum values. Simply create the generic enum value introspection query, which takes the enum name as a param:

import gql from 'graphql-tag';

const EnumValuesIntrospectionQuery = gql`
    query ($name: String!) {
        __type(name: $name) {
            enumValues {
                name
            }
        }
    }
`;
Enter fullscreen mode Exit fullscreen mode

Then use it to fetch values for the type:

import { useQuery } from 'react-apollo';

const {
    loading, error, data
} = useQuery(EnumValuesIntrospectionQuery, {
    variables: {
        name: "TreasureTypeEnum"
    }
});

const { __type: { enumValues } } = data;
const formattedEnumValues = enumValues.map(({ name }) => name);

console.log(formattedEnumValues);

// > ["GOLD_DOUBLOON", "SILVER_COIN", "EMERALD_RING"]
Enter fullscreen mode Exit fullscreen mode

For a prettier display (e.g. labels), a simple formatter that replaces underscores for spaces & text-transform: capitalize via CSS will do the trick.

Now we can render our salvaged treasure in a dropdown so the crew can select what they'd like in a HTML form. 🏴‍☠️

treasure


Thanks for reading! Anyone have a different/better approach to keep enums on FE consistent with BE?

go back