Contentful logo

Contentful Community

Best practice for adding relations (Link) between two entities (entries)

Say you have an entry named “person” and another named “zipCodes”

In the person entry there is a field person.zipCode

In the zipCodes there are two fields zipCodes.zipCode and zipCode.postOffice

In a normal database I would just add the zipCode to person.zipCode and I would be able to do the lookup.

But in contentful there is a filed named “sys” And inside a [en-US] array.

Like this

person.zipCode [en-US]

And inside

[{ "sys": { "type": "Link", "linkType": "Entry", "id": "37RxRb58CBfNmupIqKzpOp" } }]

My question is. How do I create the structure?

Is there a function that does it for me. Or do I manually create the structure myself ?

I have tried to find documentation on this. But cant find any examples in

I see a related question that is more than 6 months old. I’m not the only one struggling to understand this.

There has been no solution from Contentful other than to create the object yourself. This is what we use (TypeScript):
function CreateLinkSysObject(linkToId: string): object { return { sys: { type: "Link", linkType: "Entry", id: linkToId }}}
Then you link the reference field to that object with Contentful Management API

I have spent some days trying to make a simple script that sends data from one system into contentful.
In my opinion the product lacks vital documentation. This turns simple tasks into detective work which in turn is time consuming.

Indeed, this is a perfect example of something simple that can be either solved by better API or proper documentation. In this case we have neither.

This was a pain point for us as well. To solve it we got all the linked entries by adding/increasing the include option to our API calls. It’s talked about in the docs here:

Once we upped the include value we got the full linked entry rather than just the reference id. Then we used normalizr to flatten everything out into an easier to manage data object. It’s especially helpful when you need to perform any processing on the data upfront. For example we use it to build url strings for direct linking by joining slugs of each referenced parent all the way up our model’s tree. We also found this helpful shape the data object by removing the separate fields and sys object and keeping only what we needed. Rather than:

  fields: { title: 'Title', body: 'Post body' },
  sys: { id: 'FDFSDHHDSFDSDKJSDF', ...etc}

We have:

  title: 'Title',
  body: 'Post body',

We could just ask Contentful for the fields we use but we have found it easier to get everything and when we want to change something our schema, not our API requests, are our source of truth.

The API response also has an includes array as well as the items array that contains all the linked entries and assets (up to the depth of the include option). You could find the referenced entry by searching that includes array in a similar way normalizr produces lookup arrays but you lose on the ability to process the data.

If you have any more questions about this I’m happy to help. I just went through the pain of implementing this so it’s pretty fresh on my mind.

1 Like

Hey Kyle,

I know this thread is rather old but I wondered if you had an example of how you handled the “normalizr” side with Contentful?

I’d also love to pick your brains little more on this. Do you have somewhere I can contact you?

Happy to help out.

High level approach: we define a normalizer schema for each content type we use which applies any transformations we need to perform. This includes building urls, linking children to parents, and flattening the data structure.

Find me on twitter @krothenbaum, send me a DM there and I’m happy to discuss further.

Cheers for the information @kyle.r . I’ve followed you on Twitter now “mabai”, but I’m unable to send a message :frowning_face:

I’ll write the questions I have here as I’m sure they will help others:

  • I’ve just recently inherited a deeply nested Contenful project. I don’t always know ahead of time how big the nesting structure will be. How do you handle something like this currently, do you request with the highest includes value always?

  • Do you use any libraries you recommended for data handling, once your data has been through the “normalizer”? I can see “normalizer” only handles the structuring and doesn’t really expose any api for CRUD on the data right?

Thanks for taking the time to reply!