Nullable relational fields using Strapi, GatsbyJS and GraphQL

Dev Tutorial

Jan 7, 2021
6 min
|      by
Daniel Szymkowiak
digital badges education

tl;dr: Explicitly type your schemas for related fields to allow for null values.

The Problem

You have a model (Collection Type or Single Type) with a relational field in the CMS Strapi. If no record of the related model exists, a query will run into an error, as you cannot set the relational field to required (see this issue on the Strapi repository and this discussion on the Strapi forum).

Now, using GatsbyJS with GraphQL, this means the build process will break.

This article by Julian Alexander Murillo explains the problem very well.

The GatsbyJS Solution

What does Gatsby suggest? Always create a dummy entry on Strapi so the GraphQL definitions won’t fail. Not very neat. And not very explainable to a client neither, that he or she should always keep at least one record of the related model.

The other Gatsby suggestion is using explicit schema definitions. But it doesn’t say how to. Let’s dig into it together.

The schema-typing Solution

What you should know, is that Gatsby implicitly types your schemas for you (c.f. this link for the Gatsby docs).

The benefit of explicitly typing schemas is that you can define

  • the data structure of related models and
  • whether fields are required (non-nullable) or optional (nullable)

If fields are non-nullable, but a field in strapi is empty (or no relations are set), the query fails.


Okay, nice concept. But how will the code look? Let’s go for the following example. Say we have a Single Type which is called blog-page in Strapi, and a Collection Type called blog-post with a 1-n relationship. Our goal is to query the page with the related blog articles. The queried blog articles are then displayed in a nice overview on the blog page

Navigate to or create the gatsby-node.js file in the root of your directory. We use the createSchemaCustomization API, so our boilerplate code will look like this:

Now let’s add the type for our blog-page to above boilerplate code. If we would query the collection type, our query would be called allStrapiBlogPage. Our type definition will be StrapiBlogPage:

What happens here, is that we explicitly define the type for the fields page_title, page_subtitle and blog_post

  • The exclamation mark ( ! ) syntax marks the field as required. So our blog page needs a page_title, but does not need a page_subtitle nor a blog_post. Of course it makes sense to map the required-property of the type to the required-property of our fields in Strapi.
  • The squared brackets ( [ ... ] ) around blog_post indicates that we expect an array of the type StrapiBlogPost (see below). This holds for a 1-n relation but not for a 1-1 relation. Removing the brackets would lead to GraphQL expecting a key-value object.

Remember how every Strapi record has an id field (which is the primary key by default)? As you see, the id is not explicitly typed. What Gatsby does for us is defining the type implicitly (or automatically for all fields that we do not add to our type schema.

Last step needed is adding the type for our blog posts. Our collection is named blog-post, our query would be called allStrapiBlogPost. Our type is therefore StrapiBlogPost. The whole code will look like this:

In this scenario, all our fields are required.

That’s it! All you need to do is restart your development server and you are good to go. Your result set will contain an array of blog posts or null, if none are referenced. Something you can work with in your code using e.g. conditional rendering in the next step.

* You can find the organisation ID in the URL when you access your LinkedIn Company page as an admin.

Send, Manage and Verify Certificates

Use to design and send digital certificates that create trust - in less than 10 minutes.

Ready to start issuing digital certificates that build trust?