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

refactor(gatsby): Page dependency resolver #9732

Merged
merged 4 commits into from
Nov 8, 2018

Conversation

Moocar
Copy link
Contributor

@Moocar Moocar commented Nov 6, 2018

Anywhere in Gatsby where a graphql resolver returns a node, we need to declare a dependency from the node to the page context.path. This code is littered throughout schema. Eventually, it would be great to figure out an alternative way to declare these dependencies, since causing side effects in query resolvers isn't ideal, but in the mean time, this PR cleans up the code a bit by introducing a resolver middleware called pageDependencyResolver. It executes a given resolver and then creates a page dependency.

Another alternative would be to use graphql-middleware to run this on all field resolvers. Perhaps another day.

@Moocar Moocar requested a review from a team as a code owner November 6, 2018 04:27
@pieh
Copy link
Contributor

pieh commented Nov 8, 2018

Trying to build gatsbyjs.org with this changes I'm getting theses errors:

error
The GraphQL query from /Users/misiek/dev/gatsby/www/src/pages/docs/actions.js failed.

Errors:
  Cannot read property 'id' of undefined

  GraphQL request (40:5)
  39:     }
  40:     description {
          ^
  41:       childMarkdownRemark {
  ,Cannot read property 'id' of undefined

  GraphQL request (40:5)
  39:     }
  40:     description {
          ^
  41:       childMarkdownRemark {
  ,Cannot read property 'id' of undefined

  GraphQL request (40:5)
  39:     }
  40:     description {
          ^
  41:       childMarkdownRemark {
  ,Cannot read property 'id' of undefined

  GraphQL request (40:5)
  39:     }
  40:     description {
          ^
  41:       childMarkdownRemark {
  ,Cannot read property 'id' of undefined

  GraphQL request (40:5)
  39:     }
  40:     description {
          ^
  41:       childMarkdownRemark {
  ,Cannot read property 'id' of undefined

  GraphQL request (40:5)
  39:     }
  40:     description {
          ^
  41:       childMarkdownRemark {
  ,Cannot read property 'id' of undefined

  GraphQL request (40:5)
  39:     }
  40:     description {
          ^
  41:       childMarkdownRemark {
  ,Cannot read property 'id' of undefined

  GraphQL request (40:5)
  39:     }
  40:     description {
          ^
  41:       childMarkdownRemark {
  ,Cannot read property 'id' of undefined

  GraphQL request (40:5)
  39:     }
  40:     description {
          ^
  41:       childMarkdownRemark {
  ,Cannot read property 'id' of undefined

  GraphQL request (40:5)
  39:     }
  40:     description {
          ^
  41:       childMarkdownRemark {
  ,Cannot read property 'id' of undefined

  GraphQL request (40:5)
  39:     }
  40:     description {
          ^
  41:       childMarkdownRemark {
  ,Cannot read property 'id' of undefined

  GraphQL request (40:5)
  39:     }
  40:     description {
          ^
  41:       childMarkdownRemark {
  ,Cannot read property 'id' of undefined

  GraphQL request (40:5)
  39:     }
  40:     description {
          ^
  41:       childMarkdownRemark {
  ,Cannot read property 'id' of undefined

  GraphQL request (40:5)
  39:     }
  40:     description {
          ^
  41:       childMarkdownRemark {
  ,Cannot read property 'id' of undefined

  GraphQL request (40:5)
  39:     }
  40:     description {
          ^
  41:       childMarkdownRemark {
  ,Cannot read property 'id' of undefined

  GraphQL request (40:5)
  39:     }
  40:     description {
          ^
  41:       childMarkdownRemark {
  ,Cannot read property 'id' of undefined

  GraphQL request (40:5)
  39:     }
  40:     description {
          ^
  41:       childMarkdownRemark {
  ,Cannot read property 'id' of undefined

  GraphQL request (40:5)
  39:     }
  40:     description {
          ^
  41:       childMarkdownRemark {
  ,Cannot read property 'id' of undefined

  GraphQL request (40:5)
  39:     }
  40:     description {
          ^
  41:       childMarkdownRemark {
  ,Cannot read property 'id' of undefined

  GraphQL request (40:5)
  39:     }
  40:     description {
          ^
  41:       childMarkdownRemark {
  ,Cannot read property 'id' of undefined

  GraphQL request (40:5)
  39:     }
  40:     description {
          ^
  41:       childMarkdownRemark {
  ,Cannot read property 'id' of undefined

  GraphQL request (40:5)
  39:     }
  40:     description {
          ^
  41:       childMarkdownRemark {
  ,Cannot read property 'id' of undefined

  GraphQL request (40:5)
  39:     }
  40:     description {
          ^
  41:       childMarkdownRemark {
  ,Cannot read property 'id' of undefined

  GraphQL request (40:5)
  39:     }
  40:     description {
          ^
  41:       childMarkdownRemark {
  ,Cannot read property 'id' of undefined

  GraphQL request (40:5)
  39:     }
  40:     description {
          ^
  41:       childMarkdownRemark {
  ,Cannot read property 'id' of undefined

  GraphQL request (40:5)
  39:     }
  40:     description {
          ^
  41:       childMarkdownRemark {
  ,Cannot read property 'id' of undefined

  GraphQL request (40:5)
  39:     }
  40:     description {
          ^
  41:       childMarkdownRemark {
  ,Cannot read property 'id' of undefined

  GraphQL request (51:7)
  50:       default
  51:       description {
            ^
  52:         childMarkdownRemark {
  ,Cannot read property 'id' of undefined

  GraphQL request (40:5)
  39:     }
  40:     description {
          ^
  41:       childMarkdownRemark {
  ,Cannot read property 'id' of undefined

  GraphQL request (40:5)
  39:     }
  40:     description {
          ^
  41:       childMarkdownRemark {
  ,Cannot read property 'id' of undefined

  GraphQL request (40:5)
  39:     }
  40:     description {
          ^
  41:       childMarkdownRemark {

URL path:
  /docs/actions/
Context:
  {}
Plugin:
  none
Query:
  query usersMisiekDevGatsbyWwwSrcPagesDocsActionsJs807554310 {
    file(relativePath: {eq: "gatsby/src/redux/actions.js"}) {
      childrenDocumentationJs {
        name
        ...FunctionList
      }
    }
  }

  fragment FunctionList on DocumentationJs {
    name
    description {
      childMarkdownRemark {
        html
      }
    }
    returns {
      type {
        name
        type
        elements {
          name
          type
        }
      }
      description {
        childMarkdownRemark {
          html
        }
      }
    }
    examples {
      highlighted
    }
    params {
      name
      type {
        name
      }
      description {
        childMarkdownRemark {
          html
        }
      }
      properties {
        name
        type {
          name
        }
        default
        description {
          childMarkdownRemark {
            html
          }
        }
        properties {
          name
          type {
            name
          }
          description {
            childMarkdownRemark {
              html
            }
          }
        }
      }
    }
  }

I will do some research to hopefully pinpoint what change triggers this

if (path) {
const asArray = _.isArray(result) ? result : [result]
for (const node of asArray) {
// using module.exports here so it can be mocked
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should split those into separate module/files if we want to mock it - this feels pretty hacky

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I hated myself for doing it. But I couldn't figure out any other way to mock it properly (and had wasted hours on it by that point). Another module sounds like a good idea

const asArray = _.isArray(result) ? result : [result]
for (const node of asArray) {
// using module.exports here so it can be mocked
module.exports.createPageDependency({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need to check if node is defined here - null can be passed and in that case we definitely don't want to try to create dependency as it will fail on accessing node.id

@Moocar
Copy link
Contributor Author

Moocar commented Nov 8, 2018

@pieh added check for node being defined, and moved pageDependencyResolver into its own module.

Copy link
Contributor

@pieh pieh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🙏

@pieh pieh merged commit c2c50a8 into gatsbyjs:master Nov 8, 2018
gpetrioli pushed a commit to gpetrioli/gatsby that referenced this pull request Jan 22, 2019
Anywhere in Gatsby where a graphql resolver returns a node, we need to declare a dependency from the node to the page `context.path`. This code is littered throughout `schema`. Eventually, it would be great to figure out an alternative way to declare these dependencies, since causing side effects in query resolvers isn't ideal, but in the mean time, this PR cleans up the code a bit by introducing a resolver middleware called `pageDependencyResolver`. It executes a given resolver and then creates a page dependency.

Another alternative would be to use [graphql-middleware](https://github.com/prisma/graphql-middleware) to run this on all field resolvers. Perhaps another day.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants