gatsby: [gatsby-source-contentful] - "Single Reference" fields w/ multiple types don't generate GraphQL union types
Description
A reference field in Contentful limited to a single Entry but which accepts many types results in an incorrect GraphQL type being generated.
e.g. This “Full Slot field” is a reference to a single Entry, and accepts multiple Entry Types:
However, the fullSlot
GraphQL field incorrectly has its type set to ContentfulPlainTextModuleTest
instead of a Union(ContentfulPlainTextModuleTest|ContentfulMediaModule
) or something similar.
This results in an error running queries when multiple types appear for this reference field. e.g
query AllFullSlices {
allContentfulSliceFull {
edges {
node {
fullSlot {
__typename
}
}
}
}
}
{
"errors": [
{
"message": "Expected value of type \"ContentfulPlainTextModuleTest\" but got: [object Object].",
"locations": [
{
"line": 30,
"column": 9
}
],
"path": [
"allContentfulSliceFull",
"edges",
0,
"node",
"fullSlot"
]
}
],
"data": {
"allContentfulSliceFull": {
"edges": [
{
"node": {
"fullSlot": null
}
},
{
"node": {
"fullSlot": {
"__typename": "ContentfulPlainTextModuleTest"
}
}
}
]
}
}
}
You can see the inferred type for fullSlot
is set incorrectly in Graphiql:
Having done a lot of console.log
-ing, it seems like the issue comes from the logic that extracts an “example value” for a given node: https://github.com/gatsbyjs/gatsby/blob/3945d0132d8b3caa32940a2749ab4809bc13d310/packages/gatsby/src/schema/data-tree-utils.js#L52
Maybe a fix is to wrap any Contentful reference fields in an array?
Our current work around is just going to be to convert Contentful references into “many” references so that way the Union types are built correctly and our project can build again.
Environment
Gatsby version: 1.9.145 Node.js version: v8.9.4 Operating System: macOS 10.13.2
Actual result
Gatsby infers a single type for a singular reference field.
Expected behavior
Gatsby should infer a Union type for a singular reference field representing all possible types of the linked Entries.
Steps to reproduce
1. Create a Gatsby content type with a “single reference” field
2. Add two entries to that reference field of different types
3. Observe the generated GraphQL schema for that content type
…
This came out of investigation + context in #3495
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 3
- Comments: 15 (13 by maintainers)
Hi guys, similar case, I thought I’d ask my question here instead of opening a new issue.
How do I query for the content under “fullSlot”? It seems I can only query for __typename.
EDIT: my “fullSlot” has many references. It can accept type of Series and Products. If I have a mix of Series and Products as its references, I can only query for __typename. If however, I have many of the same type, it works.
EDIT2: just learned how GraphQL Union works and solved my own question. If anyone faces the same problem as I did, look up Inline Fragments. Here’s how it looks like:
Thanks.
Hi. Has there been any progress for this?
You actually can rename a field id in Contentful using the Webapp.
You click the lock icon and change the fields id
You might want to use the migration tool to do all these fields transformation
Yep - that’s the work around we’re going with for now just to keep moving. I’m going to try and take more of a look into the
gatsby-source-contentful
code and see if I can contribute anything here as well. Thanks for looking into it @Khaledgarbaya 🙂@ryanditjia I will transfer that to the team
That took me some time (after a lot of deletion + re-creation) to find too. Opportunity for an UX improvement, @Khaledgarbaya!
Thanks @ryanditjia for the pointer in the right direction. I got fragments working also, for anyone who wants to see code for that: https://github.com/ahimsayoga/ahimsayogajp/pull/32/files#diff-b8465397efd9d164185ae5772e69ecf0R42