americanexpress / nodes

A GraphQL JVM Client - Java, Kotlin, Scala, etc.
Apache License 2.0
307 stars 70 forks source link

Support InlineFragments #62

Open tberman opened 5 years ago

tberman commented 5 years ago

Currently there doesn't appear to be a way to support inline fragments, I am looking to do something like:

query {
  someInterface {
    ... on SomeType {
      field
    }
  }
}

I may have missed how to do this, I tried decorating a field with @GraphQLProperty but it gave me back something that looked far more like a field alias than an Inline Fragment.

Thoughts?

If this is missing and there is consensus on how to do this, I'd be happy to put together a PR!

chemdrew commented 5 years ago

Hi @tberman!

Currently this feature is not implemented. The reason for this is that I couldn't figure out an intuitive way to do this and since inline fragments were a way to simplify queries by using some OOP concepts I figured the Nodes library provided the same user friendly behavior being implemented in OOP languages but at the cost of more complex queries being constructed under the hood.

My initial thoughts on how to solve this is adding an annotation that links to a Nodes compatible class that can be traversed to build the fragment query, used like this.

@GraphQLProperty(name = "someInterface")
@GraphQLFragment(fragment = Fragment.class, on = "SomeType")
class SomeInterface {
  private String someField;
  // getters + setters for someField...
}

I believe the implementation of this should not be too difficult, but have not looked into that yet. What are your thoughts on this? Would love to brainstorm on the best solution to this.

tberman commented 5 years ago

Definitely happy to help sketch out an idea before working on it!

One thing before starting though, with unions and interfaces w/o inline fragment support you can't pull fields out that aren't on the base interface (and in the union case, they are unaccessible).

I think @GraphQLFragment would make sense. Why would you need the fragment = Fragment.class piece?

I guess I would think it wouldn't be too bad to have the data end up inside the fragment container, so something like:

class SomeInterface {
  @GraphQLFragment(on = "User")
  private User user;
  // getters + setters for user
}

class User {
  private String name;
  // getters + setters
}

And then when hydrating, we could put the data on user, so if you wanted name you would get it via:

anInstance.getUser().getName()

Thoughts?

shivamsk commented 5 years ago

@tberman @chemdrew Can you guys please provide if there is any update on this to implement union ?

tberman commented 5 years ago

@shivamsk I am happy to work on a PR once we get to some kind of general agreement on how it should work API-wise!

fefi42 commented 5 years ago

Is there any work around to this at the moment?

chandrantwins commented 2 years ago

Hi , thanks for your library. do you have any update on this support?