Gatsby: GraphQL Contenful: Question reg edges and nodes

Created on 10 Feb 2018  ·  10Comments  ·  Source: gatsbyjs/gatsby

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
    }
  }
}

question or discussion

Most helpful comment

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

@JanoshRiebesell

All 10 comments

@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?

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

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.

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.

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

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.

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

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

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

@JanoshRiebesell

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

timbrandin picture timbrandin  ·  3Comments

dustinhorton picture dustinhorton  ·  3Comments

andykais picture andykais  ·  3Comments

KyleAMathews picture KyleAMathews  ·  3Comments

ghost picture ghost  ·  3Comments