Let the client pick and choose data

One of the biggest benefits of GraphQL is that clients get the power to pick and choose data. Instead of a single API endpoint that arbitrarily sends a blob of information, we can control each and every field. Even though we front-load effort to write our GraphQL server, we’ve essentially made infinite API endpoints that fit our every need.

One way we take advantage of this at Conduit is by logically partnering GraphQL fragments and React components. Their marriage gives us strength in flexibility and organization, and is an excellent case study into the powers of GraphQL.

If you don’t know the basics of GraphQL yet, read Facebook’s intro and this REST comparison. We’ll wait for you here!

What’s a fragment?

One of the lesser-known features of GraphQL is the fragment. Designed like the ES6 spread operator, it allows us to request the same set of fields when they’re organized the same way.

For example, if we want to grab lists of people — one of Boston-based developers, and one of SF-based salespeople — and the last three times you grabbed drinks with them, we’d write the following query:

(By the way, save for a few clarity abstractions, all examples in this series actually work and run in the Conduit ecosystem. It’s the real deal!)

Note: On line 5 and 15, we’re also renaming the `companyPosition` field to `job`. This is called aliasing — the query runs the same way, but the field is keyed in the return JSON differently. This is used sometimes for convenience.

We’ve duplicated a lot of code here and, over time, this will be a hassle to maintain. We can instead write a fragment to package the fields—including any aliases we make and any relationships we grab — all together:

If you’re using Webpack, this fragment can also go in a separate .graphql file and be imported at the top of another .graphql file with #import . Nice!

Hey, React components!

As it turns out, this kind of abstraction should ring a bell: it’s similar to the way that React components encapsulate behavior and rendering.

In the same way that a parent React component doesn’t care about the child component or what it renders, a “parent” GraphQL field doesn’t care about the fragment: what fields or relationships it asks for.

We take advantage of this property by establishing one-to-one relationships between React components and GraphQL fragments. We can write fragments that define exactly what data a component needs:

For clarity, we name the fragment as the component and even put both files in the same folder:

UI/components/

- ContactItem/

- ContactItem.jsx

- ContactItem.graphql

Using the fragment and component together

When it’s time to use this component — say, in a list of contacts — we write a parent ContactItemList component that will render a list of ContactItem ’s, and we write a parent ContactItemList GraphQL query that fetches a list of ContactItem ’s:

We’re using the latest and greatest ES7 syntax to call the react-apollo HOC via a Python-like decorator, which lets us do what we affectionately call “decorating with data”. The HOC helps us write cleaner code, since the fetching logic is abstracted away into (more or less) a single line. It’s like the component magically has data as a prop. For fans of functional components, see this alternate example.

Now the dependencies are easy to follow, down to the directory structure:

GraphQL: ContactItemList.gql > ContactItem.gql

React: ContactItemList.jsx > ContactItem.jsx File structure:

==============================================

- views/Contact/ItemList/

- ContactItemList.jsx

- ContactItemList.gql - UI/components/ContactItem/

- ContactItem.jsx

- ContactItem.gql

Peace of mind

From this setup, we reap numerous benefits and take maximum advantage of what React and GraphQL have to offer.