When to disable Relay data masking

Helielson
Jusbrasil Tech
Published in
3 min readOct 29, 2018

Relay is a great framework to create React applications with data from GraphQL. One of its great feature is the Data Masking, which only makes available as prop what the component explicitly requests in its GraphQL query.

If you aren’t familiar with the Data Masking concept I advise you to read about it in the docs before reading this post. There is also a nice post written by Sibelius explaining about good practices when composing components contained by Relay.

This feature is amazing, but sometimes we need to load data that won’t be used directly for a React component. Let’s think in an application with the following components:

  • ProfileImage
  • ProfileBio
  • ProfileName

Every time any of these components is mounted we want to register an event in order to track when a profile image, biography or name is displayed.

Also, any of these components could be rendered separately, so we can’t put the event registration in a container component.

The function responsible for registering the event is something like:

So, we need to ensure that all required data from profile is loaded when the function is called.

The anti-pattern

We can load the data used by the profileInfoViewed function on each component that registers the event and pass it over to the function:

Okay, it works, but it has two problems:

  1. What if we add a field like `gender` in the function?
  2. The ProfileName component is requesting data that isn’t being used directly, breaking the “colocation” concept from Relay, which says: “GraphQL is written next to the views that rely on them.”

Solving the problems

First, we need to define the fragment of Profile data used in the function:

Now we can use it on each component the function is called. To make it work we need to disable the data masking where the fragment is referred to:

The `@relay(mask: false)` directive says to Relay: “besides loading the fields inside this fragment also make it available on this level”.

Conclusion

As I said, Relay data masking is a great feature, but sometimes it’s useful to disable it in order to reuse non-component fragments. By doing that, we are able to call the profileInfoViewed function without specifying what fields should be loaded.

Relay can’t guarantee that every profileInfoViewed call will provide the necessary data. Flow and Typescript can help you to assert the function is being called with the correct shape of data, but won't minimize the problems listed above.

Declaring the fragment also increases the maintainability of this code because if we need to change the function by adding or removing any field we don’t need to check/change every place it’s used.

If you want to know more about Relay I recommend that you read the docs. If you need any help, drop me a line on twitter @helielsonst.

Do you want to work with Relay, GraphQL, React and a lot of other fun technologies? Join us, we are hiring at Jusbrasil 🙂

https://github.com/jusbrasil/careers

--

--

Helielson
Jusbrasil Tech

In love with music, javascript, golang and a lot of others things related to technology. Software Engineer at Jusbrasil