Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using @link with a union type #24290

Closed
thekevinbrown opened this issue May 21, 2020 · 4 comments
Closed

Using @link with a union type #24290

thekevinbrown opened this issue May 21, 2020 · 4 comments
Assignees
Labels
status: needs docs review Pull request related to documentation waiting for review topic: GraphQL Related to Gatsby's GraphQL layer type: documentation An issue or pull request for improving or updating Gatsby's documentation

Comments

@thekevinbrown
Copy link
Contributor

Summary

Relevant information

We're using contentful to host our content. On our home page we have a single field called featuredMedia that can hold Articles, Reports, and Videos.

When I allow gatsby-source-contentful to infer the content types we get the ability to do this:

query MyQuery {
  allContentfulHomePage {
    nodes {
      featuredMedia {
        ... on ContentfulArticleResource {
          title
        }
        ... on ContentfulReportResource {
          title
        }
        ... on ContentfulVideoResource {
          title
        }
      }
    }
  }
}

Which is exactly what we want. However, then the user goes and removes all of the ArticleResources from Contentful and our query breaks.

No worries, off to createSchemaCustomisation!:

union MediaGroup = ContentfulArticleResource | ContentfulReportResource | ContentfulVideoResource

type ContentfulHomePage implements Node { featuredMedia: [MediaGroup] }

This starts successfully, but then the same query as above returns null. I can tell I need @link somewhere so I can get a resolver for the relationship, but I can't for the life of me figure out how to get @link to work with the union. I tried this:

type ContentfulHomePage implements Node { featuredMedia: [MediaGroup] @link }        

and this

type ContentfulHomePage implements Node { featuredMedia: [MediaGroup @link] }

and this

union MediaGroup = ContentfulArticleResource @link | ContentfulReportResource @link | ContentfulVideoResource @link

None work. How do I get this to work? I'd be happy to supply a resolver function, but I also cannot for the life of me find the default one to base a new one off of.

It's clear Gatsby has this built in and I just need to activate that behaviour again, but I can't figure out how, particularly with unions, as all the examples I find just keep showing me how to relate one type to precisely one other type.

#21852 would really help here I think.

Environment (if relevant)

Not relevant.

File contents (if changed)

(I can provide these if needed, but I think mostly it's noise. It'd be easier for me to create a reproduction I think if needed.)

@thekevinbrown thekevinbrown added the type: question or discussion Issue discussing or asking a question about Gatsby label May 21, 2020
@gatsbot gatsbot bot added the status: triage needed Issue or pull request that need to be triaged and assigned to a reviewer label May 21, 2020
@ascorbic ascorbic added topic: GraphQL Related to Gatsby's GraphQL layer and removed status: triage needed Issue or pull request that need to be triaged and assigned to a reviewer labels May 21, 2020
@vladar
Copy link
Contributor

vladar commented May 21, 2020

Hi @thekevinbrown

Contentful uses foreign key reference mechanism. Which means that the raw node data looks like this:

{
  id: `whatever`,
  featuredMedia___NODE: `someFileId`,
  // ...other node fields
}

So what happens when you write the following type definition?

type ContentfulHomePage implements Node {
  featuredMedia: [MediaGroup] @link
}

It searches for featuredMedia field in the raw node data, not featuredMedia___NODE. So you need a way to hint the actual node field to the @link directive.

Try this:

type ContentfulHomePage implements Node {
  featuredMedia: [MediaGroup] @link(from: "featuredMedia___NODE")
}

This is mentioned in the schema customization docs:

Note that when using createTypes to fix type inference for a foreign-key field created by a plugin, the underlying data will probably live on a field with a ___NODE suffix. Use the from argument to point the link extension to the correct field name. For example: author: [AuthorJson] @link(from: "author___NODE").

I hope it helps! 🤞

@thekevinbrown
Copy link
Contributor Author

thekevinbrown commented May 22, 2020

That does indeed fix my issue, thank you so much!

I never would have figured that out from the docs though to be honest. Several questions I still have that aren't very clear from the docs that contribute to this:

  • I thought gatsby-source-contentful was a source not a plugin for one, so I didn't think this section of the docs applied to me at first read. I thought plugins had plugin in the name, like gatsby-plugin-sharp. I can see the sources in the plugin library now that I look, but yeah, didn't realise.
  • What is "raw node data" versus "___NODE" data? Do you just mean the name of the field in the underlying data store that the resolver is querying? If so, I get it, if not, an explanation of what's happening here would be helpful.
  • Is there a way to get a look into the internals and figure this out while trying to use @link without passing a resolver and console.loging things to find it? I couldn't find a way to get any visibility into what's happening under the hood here, which made it pretty hard to debug.
  • What does "by" actually mean here? By what? I get that from is telling it what node to look at in the underlying store, but I don't know what by does.

As a note, I had read the source of gatsby-source-contentful and noticed the ___NODE thing, so I had tried this:

type ContentfulHomePage implements Node {
  featuredMedia___NODE: [MediaGroup]
}

Which of course just left me with a featuredMedia and also a featuredMedia___NODE field. I then assumed that the ___NODE handling was happening before my stuff and that it was actually transforming the nodes somehow. It's clear to me now that that's not the case, was just hard to figure out what the behaviour actually is for me.

Again, thanks so much for your help, was exactly what I needed!

@vladar
Copy link
Contributor

vladar commented May 22, 2020

Hey @thekevinbrown

We are going to update/improve documentation related to GraphQL in the near future so your feedback is very valuable, thank you!

I'll label this issue as documentation and we'll get back to it when working on updated GraphQL docs.

Thanks for using Gatsby 💜

@vladar vladar added status: needs dx review type: documentation An issue or pull request for improving or updating Gatsby's documentation and removed type: question or discussion Issue discussing or asking a question about Gatsby labels May 22, 2020
@danabrit danabrit added status: needs docs review Pull request related to documentation waiting for review and removed status: needs dx review labels Jul 6, 2020
@vladar
Copy link
Contributor

vladar commented Aug 31, 2020

It is documented now in this tutorial: https://www.gatsbyjs.com/tutorial/source-plugin-tutorial/#create-foreign-key-relationships-between-data

So closing this issue. Thanks for reporting! 💜

@vladar vladar closed this as completed Aug 31, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: needs docs review Pull request related to documentation waiting for review topic: GraphQL Related to Gatsby's GraphQL layer type: documentation An issue or pull request for improving or updating Gatsby's documentation
Projects
None yet
Development

No branches or pull requests

4 participants