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

[bug] ☂️ umbrella issue for schema customization issues #12272

Open
freiksenet opened this issue Mar 4, 2019 · 124 comments

Comments

@freiksenet
Copy link
Contributor

commented Mar 4, 2019

This is a meta issue for all the issues with 2.2.0, that were introduced by the schema refactoring.

What?

See the blog post for the details about why we did the refactoring and what's it all about.

See the release blog post for release notes and final updates.

How?

Install latest version of Gatsby and try running your site. Hopefully it will all just work. If you want, you could also try the two new APIs (createTypes and createResolvers).

yarn add gatsby

Changelog

gatsby@2.5.0

  • Published

gatsby@2.5.0-rc.1

  • Moved to explicit directives instead of addResolver

gatsby@2.4.0-alpha.2

  • Master back merge, upgrade graphql-compose

gatsby@2.4.0-alpha.1

gatsby@2.2.0

  • 🍾

gatsby@2.2.0-rc.2

  • Fixed a regression when empty strings mixed with dates cause stuff to not be intrepreted as dates

gatsby@2.2.0-rc.1

  • merge latest master
  • docs update

gatsby@2.2.0-alpha.6

  • merge latest master
  • better SDL parse error messages

gatsby@2.2.0-alpha.5

  • fix regression in connection naming in case types are lowercase named

gatsby@2.2.0-alpha.4

  • Fixed custom scalars not having any filters
  • Added errors when trying to override Node interface or generated filter/sort types.

gatsby@2.2.0-alpha.3

  • Added a new convenience API modelled after graphql-compose. See using-type-definitions example.
exports.sourceNodes = ({ actions, schema }) => {
  const { createTypes } = actions
  createTypes([
    schema.buildObjectType({
      name: `CommentJson`,
      fields: {
        text: `String!`,
        blog: {
          type: `BlogJson`,
          resolve(parent, args, context) {
            return context.nodeModel.getNodeById({
              id: parent.author,
              type: `BlogJson`,
            })
          },
        },
        author: {
          type: `AuthorJson`,
          resolve(parent, args, context) {
            return context.nodeModel.getNodeById({
              id: parent.author,
              type: `AuthorJson`,
            })
          },
        },
      },
      interfaces: [`Node`],
    }),
  ])
}

gatsby@2.2.0-alpha.2

  • Fixed regression with Node id field not being a String, like in current master.
  • Upgraded to graphql-compose@5.11.0
  • FilterInput types are now not prefixed by output type, reducing proliferation of types

gatsby@2.2.0-alpha.1

  • Fixed issue with pagination over null query results
  • @dontInfer(noDefaultResolvers: false) actually works
  • in createResolvers resolvers info.originalResolver is available even if there is no resolver on original field

gatsby@2.2.0-alpha.0

  • Redone alpha version with proper release version
  • Fix Node types without actual nodes not being added

gatsby@2.1.20-alpha.0

  • Initial alpha
@rexxars

This comment has been minimized.

Copy link
Member

commented Mar 5, 2019

The filters for ID fields now expect an ID as input where they previously wanted a string. This breaks certain queries, for instance:

export const query = graphql`
  query BlogPostTemplateQuery($id: String!) {
    post: sanityPost(id: { eq: $id }) {
      id
      title
    }
  }
`

Will report:

error GraphQL Error Variable "$id" of type "String!" used in position expecting type "ID".

While it may be more correct to update the query to reflect this, it is a breaking change, so I thought I would report it.

@freiksenet

This comment has been minimized.

Copy link
Contributor Author

commented Mar 5, 2019

@rexxars Nice find! I assume we used to convert ID filters to String. I'll restore old behaviour.

@freiksenet

This comment has been minimized.

Copy link
Contributor Author

commented Mar 6, 2019

Released new version.

@NicoleEtLui

This comment has been minimized.

Copy link

commented Mar 6, 2019

Trying to query the schema in the resolver:

exports.createResolvers = ({ createResolvers, schema }) => {
  createResolvers({
    MenuJson: {
      someResolver: {
        type: `String!`,
        async resolve(source, args, context, info) {
          const foo = await graphql(schema, `
            {
              allPageJson {
                nodes {
                  id
                }
              }
            }
          `, {})

          console.log(foo)

          return 'WIP'
        },
      },
    },
  })
}
TypeError: Cannot read property 'nodeModel' of undefined
         at /private/tmp/test-gatsby/node_modules/gatsby/dist/schema/resolvers.js:22:15
         at /private/tmp/test-gatsby/node_modules/gatsby/dist/schema/resolvers.js:49:44
         at Generator.next (<anonymous>)
[...]
@stefanprobst

This comment has been minimized.

Copy link
Contributor

commented Mar 6, 2019

@NicoleEtLui For queries in the field resolver, use the methods provided on context.nodeModel, i.e. you can use context.nodeModel.getAllNodes({ type: 'PageJson' }) or for more sophisticated queries you can use context.nodeModel.runQuery. There are some basic examples here.

If you need to access to the schema, note that the schema argument is just an intermediate representation - in the resolver you have access to the final built schema on info.schema.

@freiksenet

This comment has been minimized.

Copy link
Contributor Author

commented Mar 6, 2019

Published gatsby@2.2.0-alpha.3

@NicoleEtLui

This comment has been minimized.

Copy link

commented Mar 7, 2019

@stefanprobst Thanks for the quick answer and all the great work you did !

@LoicMahieu

This comment has been minimized.

Copy link
Member

commented Mar 7, 2019

Hi!
Any suggestion to handle relationships between nodes ?

For example, files are stored in JSON (without id field, assume the file name as id):
data/comments/some-uuid.json = { "message": "Hello", "postId": "some-post" }
data/posts/some-post.json = { "content": "post" }

Using the source-filesystem and transformer-json plugins, that makes the nodes have an unpredictable ID since the transformer use createNodeId(). It makes difficult to find post from comment.

@NicoleEtLui

This comment has been minimized.

Copy link

commented Mar 7, 2019

Hi !
Trying to start gatsby project with any of these in gatsby-config.js:

  • gatsby-transformer-sharp
  • gatsby-plugin-sharp
  • gatsby-plugin-manifest

will throw:

error Plugin gatsby-transformer-sharp returned an error


  Error: Cannot find module 'gatsby/dist/utils/cpu-core-count'

  - loader.js:581 Function.Module._resolveFilename
    internal/modules/cjs/loader.js:581:15

  - loader.js:507 Function.Module._load
    internal/modules/cjs/loader.js:507:25

  - loader.js:637 Module.require
    internal/modules/cjs/loader.js:637:17

  - v8-compile-cache.js:159 require
    [keemotion-corporate]/[v8-compile-cache]/v8-compile-cache.js:159:20
[...]
@pieh

This comment has been minimized.

Copy link
Contributor

commented Mar 7, 2019

@NicoleEtLui Please update gatsby-plugin-manifest and gatsby-plugin-sharp, this was fixed in those packages with #12332

@freiksenet

This comment has been minimized.

Copy link
Contributor Author

commented Mar 7, 2019

Published gatsby@2.2.0-alpha.4

@freiksenet

This comment has been minimized.

Copy link
Contributor Author

commented Mar 7, 2019

@LoicMahieu you can manually provide ids for the nodes, then you can do relationships by specifying fieldName___NODE fields.

@freiksenet

This comment has been minimized.

Copy link
Contributor Author

commented Mar 7, 2019

Published gatsby@2.2.0-alpha.5

@skinandbones

This comment has been minimized.

Copy link
Contributor

commented Mar 7, 2019

Q: Is this use case suitable for createResolvers?

I am using a remote CMS via gatsby-source-graphql which includes references to several remote files. I am currently pulling in those files with createRemoteFileNode. However, the page queries get awkward quickly because it's easy to get into situations where I need the result of the cms query (on the gatsby-source-graphql data source) to figure out which files I will need from gatsby-source-filesystem.

Ideally, I'd like to add/link/join (?) these remote file nodes into the cms nodes from gatsby-source-graphql. Is this a situation that createResolvers can help with?

@stefanprobst

This comment has been minimized.

Copy link
Contributor

commented Mar 7, 2019

@skinandbones If I am understanding correctly, the short answer is "maybe but probably not quite yet".

We do support extending field configs on types added from a third-party schema, so it is possible to add a field resolver to a type from your CMS schema with createResolvers, and use createRemoteFileNode in the resolver. For example:
https://github.com/stefanprobst/gatsby/blob/5bbfee29b5ec38f13a3070b13de4877aaddd6483/examples/using-gatsby-source-graphql/gatsby-node.js#L56-L71

The problem is that createRemoteFileNode will trigger onCreateNode API calls, and in the field resolver we have currently no way of knowing when those subsequent API calls have finished and it is safe for the resolver to return. (One approach to solve this could be #12202.) So depending on what exactly you intend to do with the remote files, this might or might not yet work.

@stefanprobst

This comment has been minimized.

Copy link
Contributor

commented Mar 7, 2019

@LoicMahieu Do you have an example project you can link to?

@skinandbones

This comment has been minimized.

Copy link
Contributor

commented Mar 7, 2019

@stefanprobst Yes, you understand correctly and the async issue makes sense. The example you linked is pretty similar to what I was expecting to do so I can give that a shot and see what happens. My plan is to run these file nodes through gatsby-transformer-sharp in the page query.

Is another viable approach to use createRemoteFileNode via the sourceNodes API (as usual) and then link those nodes into the 3rd party schema using the new API? Up to this point, I haven't been able to get into the 3rd party schema to do this.

@stefanprobst

This comment has been minimized.

Copy link
Contributor

commented Mar 7, 2019

@skinandbones sorry, i should have clarified: the part in the example i linked to is currently not yet working, exactly because of the issue that when the field resolver returns, the File node will have been created, but the ImageSharp node (which is created in the triggered onCreateNode API call) not yet.

As for the second approach, I'd be interested in your findings -- it should be possible to query for the added remote File nodes in the resolver with context.nodeModel.getAllNodes({ type: 'File' }) or with something like context.nodeModel.runQuery({ type: 'File', query: { filter: { name: { regex: "/^remote/" } } } })

LoicMahieu added a commit to LoicMahieu/test-gatsby-refactor-schema that referenced this issue Mar 7, 2019

LoicMahieu added a commit to LoicMahieu/test-gatsby-refactor-schema that referenced this issue Mar 7, 2019

@LoicMahieu

This comment has been minimized.

Copy link
Member

commented Mar 7, 2019

@stefanprobst
Here is a example:

  1. https://github.com/LoicMahieu/test-gatsby-refactor-schema
    Here we get able to link comments to post by a complex lookup on parent File.

  2. https://github.com/LoicMahieu/test-gatsby-refactor-schema/tree/custom-transformer-json
    Here we get able to link them by using a custom JSON transformer where we could transform the object and also change the id.
    This method works but: if post is deleted and reference still exists in comments, gatsby will fail.
    It could be fixed by not use the ___NODE way but the new createResolvers: demo

@baobabKoodaa

This comment has been minimized.

Copy link
Contributor

commented Mar 7, 2019

Hey, I just read this blog post about schema customization and the birthday example kinda seemed strange to me. In the example you're creating a custom resolver, which tries to resolve a date field into a Date, and falls back to a bogus value (01-01-1970) if the input date is not a proper Date. If you ever actually had a date in a real system, you would never want to replace incorrect inputs with bogus data. You would want to flag them as unknown/incorrect with something like null values. The fact that null wasn't used in the example made me wonder: is there some kind of limitation in Gatsby/GraphQL wrt. null values?

@stefanprobst

This comment has been minimized.

Copy link
Contributor

commented Mar 7, 2019

@baobabKoodaa

is there some kind of limitation in Gatsby/GraphQL wrt. null values?

No. In GraphQL, you can explicitly set if a field should be nullable or not. More info here.

@skinandbones

This comment has been minimized.

Copy link
Contributor

commented Mar 7, 2019

@stefanprobst I got this working and it works with ImageSharp. Very very cool and a game changer for working with a 3rd party schema 🎉 🎉

As for the second approach, I'd be interested in your findings -- it should be possible to query for the added remote File nodes in the resolver with context.nodeModel.getAllNodes({ type: 'File' }) or with something like context.nodeModel.runQuery({ type: 'File', query: { filter: { name: { regex: "/^remote/" } } } })

Here's what I did ...

exports.sourceNodes = async ({ actions, store, cache, createNodeId }) => {
  ... do createRemoteFileNode stuff ...
}

exports.createResolvers = ({ createResolvers, schema }) => {
  createResolvers({
    CMS_Thing: {
      thumbFile: {
        type: 'File!',
        async resolve(source, args, context, info) {
          const data = await context.nodeModel.runQuery({
            type: 'File',
            query: { filter: { fields: { ThingThumb: { eq: 'true' }, thingId: { eq: source.id } } } }
          })
          return data[0];
        }
      }
    }
  });
}

(This depends on me creating the file nodes with some fields, obviously. )

The optimal path (for my use case) will be to be able to use createRemoteFileNode in createResolvers so hopefully we can figure that out.

@lannonbr lannonbr unpinned this issue Mar 8, 2019

@stefanprobst

This comment has been minimized.

Copy link
Contributor

commented Mar 8, 2019

@skinandbones Very cool! Btw, you can use firstOnly: true in runQuery to only get the first result.

@stefanprobst

This comment has been minimized.

Copy link
Contributor

commented Jun 4, 2019

@pauleveritt unfortunately I was not able to reproduce with this basic setup -- would you be able to provide a small repro for this issue to look into? This would be very helpful, thanks!

@pauleveritt

This comment has been minimized.

Copy link

commented Jun 4, 2019

@stefanprobst Found the cause: it's 2.8.x -- want me to file a new ticket?

Imagine your gatsby-blog for YAML repo. Add this to gatsby-node.js:

exports.createResolvers = ({ createResolvers, schema }) => {
  createResolvers({
    Query: {
      allResourcesByType: {
        type: ['MarkdownRemark'],
        args: {
          resourceType: 'String'
        },
        resolve(source, args, context, info) {
          return context.nodeModel.runQuery({
            query: {
              filter: {
                frontmatter: {}
              },
              sort: { fields: ["frontmatter___title"], order: ["ASC"] },
            },
            type: `MarkdownRemark`
          })
        }
      }
    }
  })
}

In gatsby 2.7.6 you can query for allResourcesByType in the explorer. In 2.8.0-2.8.2 you get a resolve error.

@janosh

This comment has been minimized.

Copy link
Contributor

commented Jun 5, 2019

@stefanprobst I'm trying to convert tags that I specify as an array of strings in the frontmatter of my posts into a type Tag with fields title and slug where title is just the string I wrote and slug = _.kebabCase(title). I threw together this snippet

exports.sourceNodes = ({ actions, schema }) => {
  actions.createTypes([
    `type MarkdownRemark implements Node {
      frontmatter: MarkdownRemarkFrontmatter
    }`,
    `type Tag { title: String!, slug: String! }`,
    schema.buildObjectType({
      name: `MarkdownRemarkFrontmatter`,
      fields: {
        tags: {
          type: `[Tag!]`,
          resolve(source) {
            if (!source.tags) return null
            return source.tags.map(tag => ({
              title: tag,
              slug: kebabCase(tag),
            }))
          },
        },
      },
    }),
  ])
}

which works for adding the Tag type to MarkdownRemarkFrontmatter.tags. But of course, when I try to group all tags with

tags: allMarkdownRemark {
  group(field: frontmatter___tags) {
    title: fieldValue
    count: totalCount
  }
}

I get only the string I wrote into the frontmatter. I tried writing a resolver for allTags like so

exports.createResolvers = ({ createResolvers }) => {
  const resolvers = {
    Query: {
      allTags: {
        type: [`Tag`],
        resolve(source, args, context) {
          return context.nodeModel.getAllNodes({
            type: `MarkdownRemarkFrontmatterTags`,
          })
        },
      },
    },
  }
  createResolvers(resolvers)
}

but can't get it to work. Any advice?

@stefanprobst

This comment has been minimized.

Copy link
Contributor

commented Jun 7, 2019

@janosh

  • When changing the field type of frontmatter.tags from [String] to [Tag], the field argument of group would also have to be adjusted to either frontmatter___tags___title or frontmatter___tags___slug. UNFORTUNATELY this does not yet work correctly, because we don't call field resolvers for group fields, only for filter and sort fields (see #11368).
  • For the moment, you can workaround this by using a dummy filter to trigger the field resolver:
{
  allMarkdownRemark(filter: {frontmatter: {tags: {elemMatch: {title: {ne: null}}}}}) {
    group(field: frontmatter___tags___title) {
      fieldValue
      totalCount
      nodes {
        frontmatter {
          title
        }
      }
    }
  }
}

Fixing this is on my todo list -- i'll get on it asap

  • The issue with your createResolvers snippet is this: getAllNodes will retrieve nodes by type, where "node" means objects with a unique ID created by source or transformer plugins (with the createNode action). So you would have to retrieve MarkdownRemark nodes, and then further manipulate the results in the resolver.
  • Depending on your usecase, you might not even need to use createTypes, but could simply add a custom root query field to group posts by tag, and include a slug field:
// gatsby-node.js
const { kebabCase } = require(`lodash`)

exports.createResolvers = ({ createResolvers }) => {
  createResolvers({
    Query: {
      allMarkdownRemarkGroupedByTag: {
        type: [
          `type MarkdownRemarkGroup {
            nodes: [MarkdownRemark]
            count: Int
            tag: String
            slug: String
          }`,
        ],
        resolve(source, args, context, info) {
          const allMarkdownRemarkNodes = context.nodeModel.getAllNodes({
            type: `MarkdownRemark`,
          })

          const groupedByTag = allMarkdownRemarkNodes.reduce((acc, node) => {
            const { tags } = node.frontmatter
            tags.forEach(tag => {
              acc[tag] = (acc[tag] || []).concat(node)
            })
            return acc
          }, {})

          return Object.entries(groupedByTag).map(([tag, nodes]) => {
            return {
              nodes,
              count: nodes.length,
              tag,
              slug: kebabCase(tag),
            }
          })
        },
      },
    },
  })
}
@janosh

This comment has been minimized.

Copy link
Contributor

commented Jun 7, 2019

@stefanprobst Thanks for the quick reply!

So you would have to retrieve MarkdownRemark nodes, and then further manipulate the results in the resolver.

I thought about doing that but suspected that I was overlooking something and hence approaching this from the wrong angle. Thanks for clearing this up and for planning to add support for field resolvers for group fields!

Maybe another solution would be to let Tag implement Node such that Gatsby creates an allTag query automatically.

type Tag implements Node { title: String!, slug: String! }

Then all I would have to do is to actually create nodes of type Tag every time I come across a new one in the call to schema.buildObjectType for MarkdownRemarkFrontmatter. Is it possible to apply side effects like this from within resolvers? I.e. in this case check if Tag with title MyTag exists and if not createNode({type: `Tag`, title: `MyTag, slug: `my-tag` }).

@stefanprobst

This comment has been minimized.

Copy link
Contributor

commented Jun 10, 2019

@pauleveritt sorry for the late reply!

In your example, sorting should work with this:

exports.createResolvers = ({ createResolvers }) => {
  createResolvers({
    Query: {
      allResourcesByType: {
        type: ["MarkdownRemark"],
        args: {
          resourceType: "String",
        },
        resolve(source, args, context, info) {
          return context.nodeModel.runQuery({
            query: {
              sort: { fields: ["frontmatter.post_title"], order: ["DESC"] },
            },
            type: "MarkdownRemark",
          })
        },
      },
    },
  })
}

Note that both sort fields and order are arrays, and fields uses the dot-notation instead of triple underscore to separate fields. (We have to document this! EDIT: #14681)
There are two reasons why this is different in runQuery than it is when using a query string (i.e. in the Graph_i_ql explorer):

  • on list fields, scalar values will automatically be parsed as a single-item array (this is why it is possible to just say DESC). we currently don't do that with runQuery (we probably should)
  • both fields and order are GraphQLEnum fields. In Graph_i_ql you would use the enum keys, while runQuery needs the internal enum values. E.g. the fields enum separates fields by triple underscore because graphql does not allow dots, but internally this translates to fields in dot notation.
@stefanprobst

This comment has been minimized.

Copy link
Contributor

commented Jun 10, 2019

@janosh grouping on resolved fields should now work with gatsby@2.8.7

@janosh

This comment has been minimized.

Copy link
Contributor

commented Jun 10, 2019

@stefanprobst Wow, that was fast! Thanks for the update.

Is there a way to get both the title and slug of a tag in a single grouping? I can only figure out how to group by either and then only have access to one of them.

{
  tags: allMarkdownRemark {
    group(field: frontmatter___tags___(slug|title)) {
     (slug|title): fieldValue
      count: totalCount
    }
  }
}

If I try to group by frontmatter___tags instead,

{
  tags: allMarkdownRemark {
    group(field: frontmatter___tags) {
      tag: fieldValue
      count: totalCount
      
    }
  }
}

I get only a single result

{
  "data": {
    "tags": {
      "group": [
        {
          "tag": "[object Object]",
          "count": 52
        }
      ]
    }
  }
}
@stefanprobst

This comment has been minimized.

Copy link
Contributor

commented Jun 12, 2019

@janosh you can only group by one field (hierarchical sub-groupings are not possible). if you need the values of both title and slug, you can group by one, and get the value of the other from the results (maybe I'm misunderstanding?):

{
  allMarkdownRemark {
    group(field: frontmatter___tags___title) {
      fieldValue
      totalCount
      nodes {
        frontmatter {
          tags {
            slug
            title
          }
        }
      }
    }
  }
}
@janosh

This comment has been minimized.

Copy link
Contributor

commented Jun 12, 2019

@stefanprobst That doesn't fit my use case but it's only a minor inconvenience. Thanks for all the awesome work you're putting into schema customization!

@laradevitt

This comment has been minimized.

Copy link
Contributor

commented Jul 9, 2019

I've been having an issue since 2.2.0 which seems to be OS-related. I would be grateful to get another Windows 10 user's eyes on it for a test so I can either confirm or rule it out: escaladesports/gatsby-plugin-netlify-cms-paths#10

Thanks!

@stefanprobst

This comment has been minimized.

Copy link
Contributor

commented Jul 9, 2019

@laradevitt I don't currently have access to a windows machine, and I'm also not familiar with gatsby-plugin-netlify-cms-paths -- but does it work if you replace the path on frontmatter.image to a relative path, i.e. ../static/media/gatsby-astronaut.png ?

@laradevitt

This comment has been minimized.

Copy link
Contributor

commented Jul 9, 2019

@stefanprobst - Thanks for your reply! Yes, it does, but the point of the plugin is that you should not have to use relative paths:

A gatsby plugin to change file paths in your markdown files to Gatsby-friendly paths when using Netlify CMS to edit them.

I've created a pull request with a fix that makes the returned relative path platform agnostic.

I still don't know why it broke with 2.2.0. 🤷‍♀

@stefanprobst

This comment has been minimized.

Copy link
Contributor

commented Jul 9, 2019

@laradevitt ah, sorry, should have checked the readme.

I still don't know why it broke with 2.2.0.

This is very probably a regression in Gatsby, as with 2.2.0 type inference changed a bit -- but normalizing paths in gatsby-plugin-netlify-cms-paths definitely seems more correct 👍

@ryanwiemer

This comment has been minimized.

Copy link
Contributor

commented Jul 25, 2019

@stefanprobst

I just created a new ticket related to schema customization. If it is better for me to close that and put it in this umbrella thread just let me know.

#16099

Thanks!

@NickyMeuleman

This comment has been minimized.

Copy link
Member

commented Aug 6, 2019

Description

Arguments in a graphQL query don't work when using schema customization.

After watching the learn with Jason stream on advanced GraphQL(broken up in multiple parts due to technical difficulties) I incorporated a lot of what was talked about into my theme.
However using graphQL arguments (like filter and sort) that rely on values from the customized schema doesn't work.

Steps to reproduce

run this branch of my theme locally.
Fire up /___graphql and query allBlogPosts.
Now try to query allBlogPosts again with a sort by descending date.
RESULT: no change in order (ASC, or DESC)

Example 2

Query for all posts and show their titles.

query MyQuery {
  allBlogPost {
    nodes {
      title
    }
  }
}

RESULT: works

now query for all posts that are have a tag with slug "lorem-ipsum"

query MyQuery {
  allBlogPost(filter: {tags: {elemMatch: {slug: {eq: "lorem-ipsum"}}}}) {
    nodes {
      title
    }
  }
}

RESULT: empty nodes array.

temporary workaround, possible reason why it doesn't work?

Try to query a single BlogPost (picks first one by default if no arguments are given).
Now try to query blogPost(slug: {eq: "herp-derpsum"}).
This works, I think because I added the slug to the MdxBlogPost node.
https://github.com/NickyMeuleman/gatsby-theme-nicky-blog/blob/d29c966e639f4733caf9ee43e9f5755df42db71d/theme/gatsby-node.js#L209-L210

It seems like the graphql arguments use data from the MdxBlogPost node rather than the eventual result after it runs its resolvers. Is my suspicion close?

Environment

System:
OS: Linux 4.19 Ubuntu 18.04.2 LTS (Bionic Beaver)
CPU: (4) x64 Intel(R) Core(TM) i5-2500K CPU @ 3.30GHz
Shell: 4.4.19 - /bin/bash
Binaries:
Node: 12.4.0 - /tmp/yarn--1565124765846-0.45931526383359134/node
Yarn: 1.16.0 - /tmp/yarn--1565124765846-0.45931526383359134/yarn
npm: 6.9.0 - ~/.nvm/versions/node/v12.4.0/bin/npm
Languages:
Python: 2.7.15+ - /usr/bin/python

Additional notes

Relevant parts of code are in gatsby-node.js in the theme directory.
specifically the createSchemaCustomization and onCreateNode lifecycles.
I tried to heavily comment to show my though process.

@stefanprobst

This comment has been minimized.

Copy link
Contributor

commented Aug 8, 2019

@NickyMeuleman sorry haven't had time yet to look closely but it seems you are missing a link extension on the BlogPost interface.

You define your MdxBlogPost.tags field to link by name:

tags: {
  type: "[Tag]",
  extensions: {
    link: { by: "name" },
  },
},

in the typedefs for the BlogPost interface you have:

  interface BlogPost @nodeInterface {
    tags: [Tag]
  }

Does it work with

  interface BlogPost @nodeInterface {
    tags: [Tag] @link(by: "name")
  }
@stefanprobst

This comment has been minimized.

Copy link
Contributor

commented Aug 9, 2019

Related: #16466

@NickyMeuleman

This comment has been minimized.

Copy link
Member

commented Aug 9, 2019

After adding your suggestion, querying allBlogPost with a filter based on a tag did work! 🎉 Thanks!

n the future, will I be able to remove the @link from the interface, since Tags might be linked differently per type that implements the BlogPost interface? (same question for Author, filtering there doesn't work, even with the @link moved up to the interface level.

@stefanprobst

This comment has been minimized.

Copy link
Contributor

commented Aug 11, 2019

@NickyMeuleman
thanks for experimenting!
after looking at this i think it's something we need to fix in core: both issues have to with the fact that we use the interfaces's resolver when manually preparing nodes so we can run a filter on them. instead, we should run the resolver of the type we get from the interface's resolveType, which is also what happens when graphql processes the selection set.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
You can’t perform that action at this time.