Graphql-go: Composing multiple fragments seems incorrect

Created on 30 Mar 2017  路  8Comments  路  Source: graph-gophers/graphql-go

Hi, great project, I'm running into an issue composing multiple fragments. Let me know if this is a new issue and I will create a more complete test case, but here's a quick graphiql screenshot showing the problem:

image

If two fragments both request data from a child object (in this case the account child of a message object), the data seems to only come through from one of them (here the id comes from B but A doesn't get the email field it requested). If B is removed, then email comes through fine.

Thanks for your hard work, let me know if anything jumps out at you, or if it would be useful to have a full self-contained test case here.

Most helpful comment

graphql-go is now able to properly execute those queries. I still need to implement the validation steps so it gives an error if your query is bad.

All 8 comments

I'm looking into this now. Here's the failing test case, any pointers to where the problem might be much appreciated:

func TestComposedFragments(t *testing.T) {
    gqltesting.RunTests(t, []*gqltesting.Test{
        {
            Schema: starwarsSchema,
            Query: `
                {
                    composed: hero(episode: EMPIRE) {
                        name
                        ...friendsNames
                        ...friendsIds
                    }
                }

                fragment friendsNames on Character {
                    name
                    friends {
                        name
                    }
                }

                fragment friendsIds on Character {
                    name
                    friends {
                        id
                    }
                }
            `,
            ExpectedResult: `
                {
                    "composed": {
                        "name": "Luke Skywalker",
                        "friends": [
                            {
                                "id": "1002",
                                "name": "Han Solo"
                            },
                            {
                                "id": "1003",
                                "name": "Leia Organa"
                            },
                            {
                                "id": "2000",
                                "name": "C-3PO"
                            },
                            {
                                "id": "2001",
                                "name": "R2-D2"
                            }
                        ]
                    }
                }
            `,
        },
    })
}

Current output:

$ go test -v graphql_test.go -run TestComposedFragments
=== RUN   TestComposedFragments
--- FAIL: TestComposedFragments (0.00s)
    testing.go:47: got:  {"composed":{"friends":[{"id":"1002"},{"id":"1003"},{"id":"2000"},{"id":"2001"}],"name":"Luke Skywalker"}}
    testing.go:48: want: {"composed":{"friends":[{"id":"1002","name":"Han Solo"},{"id":"1003","name":"Leia Organa"},{"id":"2000","name":"C-3PO"},{"id":"2001","name":"R2-D2"}],"name":"Luke Skywalker"}}
FAIL
exit status 1

Thanks for the test case. You are completely right, this is a case I never considered. I'll take care of it.

Here's a smaller test case without fragments:

func TestRepeatedField(t *testing.T) {
    gqltesting.RunTests(t, []*gqltesting.Test{
        {
            Schema: starwarsSchema,
            Query: `
                {
                    composed: hero(episode: EMPIRE) {
                        name
                        friends {
                            name
                        }
                        friends {
                            id
                        }
                    }
                }
            `,
            ExpectedResult: `
                {
                    "composed": {
                        "name": "Luke Skywalker",
                        "friends": [
                            {
                                "id": "1002",
                                "name": "Han Solo"
                            },
                            {
                                "id": "1003",
                                "name": "Leia Organa"
                            },
                            {
                                "id": "2000",
                                "name": "C-3PO"
                            },
                            {
                                "id": "2001",
                                "name": "R2-D2"
                            }
                        ]
                    }
                }
            `,
        },
    })
}

Here's a full set of related tests: https://github.com/graphql/graphql-js/blob/master/src/validation/__tests__/OverlappingFieldsCanBeMerged-test.js

This is not trivially solved. I have to think about it for a bit.

Thank you @neelance, I appreciate it, please let me know if I can help in any way.

graphql-go is now able to properly execute those queries. I still need to implement the validation steps so it gives an error if your query is bad.

Awesome, thank you, I can confirm this fixes the problem!

Validation of overlapping fields is now implemented.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jakubdal picture jakubdal  路  6Comments

AndreasBackx picture AndreasBackx  路  4Comments

JitinGuglani picture JitinGuglani  路  6Comments

vladimiroff picture vladimiroff  路  6Comments

bsr203 picture bsr203  路  6Comments