Neo4j-graphql-js: bug: aliases break

Created on 29 Mar 2018  路  3Comments  路  Source: neo4j-graphql/neo4j-graphql-js

Bug: aliased queries break.

Aliased queries can be set up in app level queries (example) or are automatically generated when the client does query merging

Example using the schema and data used in neo4j-graphql-js:

    {
      Movie(first: 2) {
        title
        a1: actors {
          name
        }
        a2: actors(first: 1, offset: 1) {
          movies {
            title
          }
        }
      }
    }

Actual output:

    {
      "data": {
        "Movie": [
          {
            "title": "Toy Story",
            "a1": [
              {
                "name": null
              }
            ],
            "a2": [
              {
                "movies": [
                  {
                    "title": "3 Ninjas: High Noon On Mega Mountain"
                  },
                  {
                    "title": "Toy Story"
                  }
                ]
              }
            ]
          },
          {
            "title": "Jumanji",
            "a1": [
              {
                "name": null
              }
            ],
            "a2": [
              {
                "movies": [
                  {
                    "title": "Jumanji"
                  }
                ]
              }
            ]
          }
        ]
      }
    }

Expected output:

    {
      "data": {
        "Movie": [
          {
            "title": "Toy Story",
            "a1": [{
                "name": "Tom Hanks"
              }, {
                "name": " Jim Varney"
              }, {
                "name": " Don Rickles"
              }, {
              "name": " Tim Allen"
            }],
            "a2": [{
                "movies": [{
                    "title": "3 Ninjas: High Noon On Mega Mountain"
                  }, {
                    "title": "Toy Story"
                }]
            }]
          },
          {
            "title": "Jumanji",
            "a1": [{
                "name": "Robin Williams"
              }, {
                "name": " Bradley Pierce"
              }, {
                "name": " Kirsten Dunst"
              }, {
                "name": " Jonathan Hyde"
            }],
            "a2": [{
                "movies": [{
                    "title": "Jumanji"
                }]
            }]
          }
        ]
      }
    }

The names in a1 are null when they are not in the a2 selectionSet. Also, a1 loses entries because of the pagination in a2.

The resulting query is

MATCH (movie:Movie {})
RETURN movie {
  .title ,
  actors: [
    (movie)<-[:ACTED_IN]-(movie_actors:Actor) | movie_actors { .name }
  ],
  actors: [
    (movie)<-[:ACTED_IN]-(movie_actors:Actor) | movie_actors {movies: [(movie_actors)-[:ACTED_IN]->(movie_actors_movies:Movie) | movie_actors_movies { .title }] }
  ][1..2]
} AS movie SKIP 0 LIMIT 2

All 3 comments

Hm. It may be because this lib traverses the whole tree in one go, while aliasing happens in the graphql server realm.

So the solution needs to involve resolvers? Maybe in the query, map keys which have an alias defined in resolveInfo to their alias, and at setup time, wrap the resolvers with a schema-aware function that adds field-level resolvers as pre-processing before user defined resolvers, unaliasing the keys again per resolveInfo. Along these lines:

    Movies: {
      actors: (obj, .., resolveInfo) => obj[original_key_via_resolveInfo_alias]
    }

Not sure resolveInfo tells which alias a field is called for at a given call.

I noticed this behavior as well. Would be great if we could get some resolution on it

Has anyone found a workaround for this?

Was this page helpful?
0 / 5 - 0 ratings