aws / aws-appsync-community

The AWS AppSync community
https://aws.amazon.com/appsync
Apache License 2.0
506 stars 32 forks source link

selectionSetGraphQL is incomplete when using Fragments #142

Open bboure opened 3 years ago

bboure commented 3 years ago

Hi,

Currently, the selectionSetGraphQL field doe not give enough information about the selectionSet when Fragments are involved.

Example:

Schema:

type Bar {
    someField(someArg: String): String
}

type Foo {
    bar: Bar
    buzz: String
    bizz: String
}

type Query {
    foo(arg: String): Foo
}

schema {
    query: Query
}

Query:

query  {
  foo(arg: "hi") {
    ...FooFrag
    bar {
     ...BarFrag 
    }
    bizz
  }
}

fragment FooFrag on Foo {
    buzz
}

fragment BarFrag on Bar {
    someField(someArg: "hello")
}

In the resolver for foo, selectionSetGraphQL contains:

{
  ...FooFrag
  bar {
    ...BarFrag
  }
  bizz
}

There is no info about the FooFrag and BarFrag fragments.

The expected result should be either

{
  ...FooFrag
  bar {
    ...BarFrag
  }
  bizz
}

fragment FooFrag on Foo {
    buzz
}

fragment BarFrag on Bar {
    someField(someArg: "hello")
}

or be "resolved", like so:

{
  buzz
  bar {
    someField(someArg: "hello")
  }
  bizz
}

Alternatively, fragments could come in an extra info field (something like $ctx.info.fragmentsGraphQL)

The goal to that is to be able to grab the someArg value from the someField field. selectionSetList and $ctx.args don't contain that information.

Here, I would like to be able to use one single resolver for foo and resolve the full tree (I don't want an extra resolver for someField under Bar)

Hope that makes sense.

EDIT: Another option would be to receive the FULL (top) query as a string. That way, we could just parse it and extract whatever we need. That would also allow other advanced usage.

Thanks!

shawnmclean commented 2 years ago

Is this something that can be used to capture the whole query to be forwarded to a downstream HTTP resolver? Using it as a proxy.

Woodz commented 1 year ago

I have just encountered this massive limitation of AppSync. I wanted to write optimized resolvers that would only return the data requested but since fragment information is not passed to the resolver, I had to create a custom GQL TS codegen plugin that inline fragments in the client operations before calling AppSync so that the full selectionSetGraphQL was passed to the resolver.

IMHO this a massive disappointment and limitation of AppSync given that fragments are best practice and the resolver should be able to look at the selection set to determine what queries to make

Tenrys commented 1 year ago

You can use the selection list that AppSync returns to get all the requested fields including the ones requested by fragments.

However, being unable to read the composition of the fragment makes it difficult (impossible?) to handle arguments on a field.

This ties in with the following issue: https://github.com/aws/aws-appsync-community/issues/185

PatrykMilewski commented 1 year ago

While query can be recreated out of selectionSetList, it doesn't include inlined fragments, which are impossible to recreate

ignaciolarranaga commented 1 year ago

Yep, found the same problem, I think it should be either the fragment resolved (preferred) or additional metadata added.

amine-mf commented 2 months ago

This has been here for 4 years, I'm not sure it is even worth discussing it ! But it is very annoying that the "Inline Fragment" are present in the selectionSetGraphQL and not the Fragments. You loose all the purpose of using GraphQL when you face this kind of limitations ! In a perfect world, this would be parsed already by AppSync and passed in selectionSetList. Did anyone find an effective workaround to this?

amine-mf commented 1 month ago

Depending on what graphql-client you are using, you can intercept the queries to "force inline" the fragments, we are doing it using a Urql Exchange. Obviously you need to parse selectionSetGraphQL to generate a full selection set in your resolvers.

PatrykMilewski commented 1 month ago

We are doing the same as @amine-mf It's not the perfect solution, as clients needs to be aware of that limitation