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

GraphQL returning all children from a structure when requesting multiple entry types (3.4.0-RC3) #5481

Closed
samput opened this issue Jan 23, 2020 · 6 comments
Assignees
Labels
graphql ⚙️ features related to the GraphQL API
Milestone

Comments

@samput
Copy link

samput commented Jan 23, 2020

Description

Using Craft CMS version 3.4.0-RC3. When querying children by type from a structure with GraphQL it returns all children when requesting multiple types.

Steps to reproduce

I have a section 'Pipeline' with a structure set up like so:

- Quarter (entryType: quarter)
    - Platform (entryType: platform)
        - Ongoing (entryType: ongoing)
        - Monthly (entryType: monthly)

GraphQL query - multiple children types:

{
  quarters: entries (section: "pipeline", type: "quarter") {
    id
    title
    platforms: children (type: "platform") {
      id
      title
      ongoing: children (type:"ongoing") {
        id
        title
      }
      monthly: children (type:"monthly") {
        id
        title
      }
    }
  }
}

Response - multiple children types:
For both ongoing and monthly it returns all the children.

{
  "data": {
    "quarters": [
      {
        "id": "14",
        "title": "Q1 2020",
        "platforms": [
          {
            "id": "136",
            "title": "Platform Name",
            "ongoing": [
              {
                "id": "155",
                "title": "Q1 2020 - Platform Name - Ongoing"
              },
              {
                "id": "158",
                "title": "Q1 2020 - Platform Name - January"
              },
              {
                "id": "161",
                "title": "Q1 2020 - Platform Name - February"
              },
              {
                "id": "164",
                "title": "Q1 2020 - Platform Name - March"
              }
            ],
            "monthly": [
              {
                "id": "155",
                "title": "Q1 2020 - Platform Name - Ongoing"
              },
              {
                "id": "158",
                "title": "Q1 2020 - Platform Name - January"
              },
              {
                "id": "161",
                "title": "Q1 2020 - Platform Name - February"
              },
              {
                "id": "164",
                "title": "Q1 2020 - Platform Name - March"
              }
            ]
          }
        ]
      },
      {
        "id": "17",
        "title": "Q2 2020",
        "platforms": []
      },
      {
        "id": "20",
        "title": "Q3 2020",
        "platforms": []
      },
      {
        "id": "23",
        "title": "Q4 2020",
        "platforms": []
      }
    ]
  }
}

However if I only request one child type, it works as expected e.g.

GraphQL query - ongoing children type:

{
  quarters: entries (section: "pipeline", type: "quarter") {
    id
    title
    platforms: children (type: "platform") {
      id
      title
      ongoing: children (type:"ongoing") {
        id
        title
      }
    }
  }
}

Response - ongoing children type:

{
  "data": {
    "quarters": [
      {
        "id": "14",
        "title": "Q1 2020",
        "platforms": [
          {
            "id": "136",
            "title": "Platform Name",
            "ongoing": [
              {
                "id": "155",
                "title": "Q1 2020 - Platform Name - Ongoing"
              }
            ]
          }
        ]
      },
      {
        "id": "17",
        "title": "Q2 2020",
        "platforms": []
      },
      {
        "id": "20",
        "title": "Q3 2020",
        "platforms": []
      },
      {
        "id": "23",
        "title": "Q4 2020",
        "platforms": []
      }
    ]
  }
}

GraphQL query - monthly children type:

{
  quarters: entries (section: "pipeline", type: "quarter") {
    id
    title
    platforms: children (type: "platform") {
      id
      title
      monthly: children (type:"monthly") {
        id
        title
      }
    }
  }
}

Response - monthly children type:

{
  "data": {
    "quarters": [
      {
        "id": "14",
        "title": "Q1 2020",
        "platforms": [
          {
            "id": "136",
            "title": "Platform Name",
            "monthly": [
              {
                "id": "158",
                "title": "Q1 2020 - Platform Name - January"
              },
              {
                "id": "161",
                "title": "Q1 2020 - Platform Name - February"
              },
              {
                "id": "164",
                "title": "Q1 2020 - Platform Name - March"
              }
            ]
          }
        ]
      },
      {
        "id": "17",
        "title": "Q2 2020",
        "platforms": []
      },
      {
        "id": "20",
        "title": "Q3 2020",
        "platforms": []
      },
      {
        "id": "23",
        "title": "Q4 2020",
        "platforms": []
      }
    ]
  }
}

Additional info

  • Craft version: 3.4.0-RC3
  • PHP version: 7.3.11
  • Database driver & version: MySQL 5.7.24
  • Plugins & versions: Feed Me 4.2.0.1, Redactor 2.5.0
@andris-sevcenko andris-sevcenko self-assigned this Jan 23, 2020
@andris-sevcenko andris-sevcenko added the graphql ⚙️ features related to the GraphQL API label Jan 23, 2020
@andris-sevcenko
Copy link
Contributor

The issue occurs because children is not a real field as far as Craft custom fields go, but rather a construct created for eager-loading.

For example, if it were an entry field or a matrix field, this would work because internally relational fields resolve to be element queries so that you can apply more parameters to them.

There was a similar issue for Matrix fields (#5008), which looks the same as your problem, but it cannot be solved the same way.

As most GraphQL querying issues, this dead-ends sinceGraphQL is wrapping around element queries, so is often limited by the element query's features.

The best approach here would be if Craft itself had a concept of alias in element queries, which is an issue I'll bring up internally and then update this issue.

@andris-sevcenko
Copy link
Contributor

@samput it's still possible, however, to fetch all the children and then just differentiate or sort the data on the frontend.

For example:

{
  quarters: entries(section: "pipeline", type: "quarter") {
    id
    title
    platforms: children {
      id
      title
      children {
        __typename
        id
        title
      }
    }
  }
}

would produce

{
  "data": {
    "quarters": [{
        "id": "14",
        "title": "Q1 2020",
        "platforms": [{
          "id": "136",
          "title": "Platform Name",
          "children": [{
              "__typename": "pipelineSection_ongoing_Entry",
              "id": "155",
              "title": "Q1 2020 - Platform Name - Ongoing"
            },
            {
              "__typename": "pipelineSection_monthly_Entry",
              "id": "158",
              "title": "Q1 2020 - Platform Name - January"
            },
            {
              "__typename": "pipelineSection_monthly_Entry",
              "id": "161",
              "title": "Q1 2020 - Platform Name - February"
            },
            {
              "__typename": "pipelineSection_monthly_Entry",
              "id": "164",
              "title": "Q1 2020 - Platform Name - March"
            }
          ]
        }]
      },
      {
        "id": "17",
        "title": "Q2 2020",
        "platforms": []
      },
      {
        "id": "20",
        "title": "Q3 2020",
        "platforms": []
      },
      {
        "id": "23",
        "title": "Q4 2020",
        "platforms": []
      }
    ]
  }
}

@samput
Copy link
Author

samput commented Jan 24, 2020

Thanks @andris-sevcenko for looking in to this. Yeah it's not a deal breaker, my plan was to separate them on the front-end by type, would be nice to have the aliases, but it's not the end of the world.

@andris-sevcenko
Copy link
Contributor

@samput FWIW I see the benefit in offloading such operation to the query itself so you don't have to deal with that in the front-end logic, so I'm keeping this issue open until we come to a decision about it.

@andris-sevcenko andris-sevcenko added this to the 3.5 milestone Feb 17, 2020
@andris-sevcenko
Copy link
Contributor

@samput we're planning on adding aliasing support for element queries in 3.5, which will resolve this in a more elegant manner.

@andris-sevcenko
Copy link
Contributor

Alright, just added this for Craft 3.5!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
graphql ⚙️ features related to the GraphQL API
Projects
None yet
Development

No branches or pull requests

2 participants