Salvaging GraphQL Enums from BE for FE ⚓️
Tags: graphql, react, tutorial, microservices
Published: 2020-08-28 16:33:57

_Leveraging [introspection queries](https://graphql.org/learn/introspection/) 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](https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html) 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:
- You could copy&paste them from the BE to the FE codebase, but that's bad practice. 🤔
- A simple endpoint could provide these enums, but that requires effort to build/maintain. 🤔
- A shared library of types/enums could be depended on by both repositories, but that's a pain to keep updated. 🤔
- Or you could use GraphQL's built-in [`IntrospectionQuery`](https://graphql.org/learn/introspection/) to determine them, which I recently used to refactor away from the first^ method in a FE application. ✅

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](https://i.giphy.com/media/WPfXFjQqHWavS/giphy.gif)

## 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:

```java
enum TreasureTypeEnum {
    GOLD_DOUBLOON,
    SILVER_COIN,
    EMERALD_RING
}
```

## 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:

```js
import gql from 'graphql-tag';

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

Then use it to fetch values for the type:

```jsx
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"]
```

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](https://i.giphy.com/media/xT1XGzAnABSXy8DPCU/giphy.gif)

---

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