gatsbyjs / gatsby

The best React-based framework with performance, scalability and security built in.
https://www.gatsbyjs.com
MIT License
55.28k stars 10.31k forks source link

GraphQL Contenful: Question reg edges and nodes #3962

Closed designbyadrian closed 6 years ago

designbyadrian commented 6 years ago

Is there a particular reason why a basic query looks like this:

{
  allContentfulAsset {
    edges {
      node {
        title
        resize(width: 100) {
          src
          width
          height
        }
      }
    }
  }
}

and not this:

{
  allContentfulAsset {
    title
    resize(width: 100) {
      src
      width
      height
    }
  }
}

❔

rockchalkwushock commented 6 years ago

@designbyadrian

Any of the queries that start with all will return an array so you have the edges key with the nodes of whatever the data set is inside the array. Even if the query was for one item from allContentfulAsset it would return as an array of one item.

If you are wanting to query one individual item I would imagine in the case of the contentful plugin that there is a contentfulAsset query you can use instead. Do you have the ability to use the GraphiQL IDE with the development api?

designbyadrian commented 6 years ago

I understand the difference between single and many queries, but don't understand why "edges" and "nodes" have to be exposed to graphQL?

rockchalkwushock commented 6 years ago

Ah gotcha, to be honest not quite sure about that myself. I believe Facebook has the spec open sourced. It might say why that is the case there.

designbyadrian commented 6 years ago

My wild guess is that's the default data structure contentful exposes. It'd be neat if gatsby-contentful could transform the data for more ease of use.

pieh commented 6 years ago

It's actually gatsby that does that, one reason is that it allows You to do more things than just to get list of results. For example this is what You could do (using gatsby website as example here):

allMarkdownRemark {
  totalCount #total number of posts
  listOfBlogPostAuthors:distinct(field:frontmatter___author) #list of distinct author names
  group(field:frontmatter___author) { # get posts grouped by authors 
    fieldValue # author name
    totalCount # count of author posts
    edges {
      node {
        frontmatter {
          title
        }
      }
    }
  }
}

Which would give me:

{
  "data": {
    "allMarkdownRemark": {
      "totalCount": 474,
      "listOfBlogPostAuthors": [
        "Amberley Romo",
        "Arden de Raaij",
        "Benjamin Read",
        "David James",
        "Dustin Schau",
        "Fernando Poumian",
        "Ian Sinnott",
        "Josh Weaver",
        "Kalin Chernev",
        "Kostas Bariotis",
        "Kyle Mathews",
        "Moreno Feltscher",
        "Nahuel Scotti",
        "Pierre Burgy",
        "Robin Vasan",
        "Ross Whitehouse",
        "Sam Bhagwat",
        "Samuel Goudie",
        "Shannon Soper",
        "Tal Bereznitskey",
        "Tim Arney",
        "Vlad Pasculescu"
      ],
      "group": [ // skipping most of the results to just show some examples here
       {
          "fieldValue": "Kyle Mathews",
          "totalCount": 7,
          "edges": [
            {
              "node": {
                "frontmatter": {
                  "title": "Gatsby's first beta release"
                }
              }
            },
            {
              "node": {
                "frontmatter": {
                  "title": "Announcing Gatsby 1.0.0 πŸŽ‰πŸŽ‰πŸŽ‰"
                }
              }
            },
            {
              "node": {
                "frontmatter": {
                  "title": "What's coming in Gatsby 1.0"
                }
              }
            },
            {
              "node": {
                "frontmatter": {
                  "title": "Web Performance 101β€”also, why is Gatsby so fast?"
                }
              }
            },
            {
              "node": {
                "frontmatter": {
                  "title": "Community Roundup #1"
                }
              }
            },
            {
              "node": {
                "frontmatter": {
                  "title": "Making website building fun"
                }
              }
            },
            {
              "node": {
                "frontmatter": {
                  "title": "Gatsbygram Case Study"
                }
              }
            }
          ]
        },
        {
          "fieldValue": "Sam Bhagwat",
          "totalCount": 1,
          "edges": [
            {
              "node": {
                "frontmatter": {
                  "title": "How Boston.gov used Gatsby to be selected as an Amazon HQ2 candidate city"
                }
              }
            }
          ]
        },
        {
          "fieldValue": "Shannon Soper",
          "totalCount": 3,
          "edges": [
            {
              "node": {
                "frontmatter": {
                  "title": "Introducing the Gatsby UX Research Program"
                }
              }
            },
            {
              "node": {
                "frontmatter": {
                  "title": "Building Sites with Headless CMSs"
                }
              }
            },
            {
              "node": {
                "frontmatter": {
                  "title": "Building a Site with React and Contentful"
                }
              }
            }
          ]
        },
      ]
    }
  }
}

notice - I didn't even use topmost edges field here. Agree that it would be used 99% of the time, but this gives more flexibility.

This is also somewhat based on https://facebook.github.io/relay/graphql/connections.htm

designbyadrian commented 6 years ago

I appreciate your examples, but could you point out where{ edges: { node: x } } couldn't be replaced by just x ?

Edit: I saw now in "Relay Cursor Connections Specification" that it's GraphQL standard.

pieh commented 6 years ago

if we replaced { edges { node: x } } with just x we couldn't do things I showed above :)

janosh commented 6 years ago

@pieh Why not? Sorry if its obvious but I'm new to all this and have been wondering the same thing.

romines commented 6 years ago

It is related to GraphQL pagination, apparently. This post gives a little context. See the section titled 'Relay cursor connections'

@JanoshRiebesell

ghost commented 5 years ago

Quote from Sashko Stubailo:

An edge has metadata about one object in the paginated list, and includes a cursor to allow pagination starting from that object.

A node represents the actual object you were looking for.