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

Input polymorphism #415

Closed
hasyee opened this issue Mar 4, 2018 · 3 comments
Closed

Input polymorphism #415

hasyee opened this issue Mar 4, 2018 · 3 comments
Labels
💭 Strawman (RFC 0) RFC Stage 0 (See CONTRIBUTING.md)

Comments

@hasyee
Copy link

hasyee commented Mar 4, 2018

I know there are some related issue, but almost all of them propose only Input Union types.
I think GraphQL is very powerful at the really complex data models, but the complex data models are usually designed to strongly polymorph. The greatest lack of feature in GraphQL is the input polymorphism. This is missing painfully and GraphQL really needs this feature.
I recommend a more generic way without modifying the syntax. This needs only to enhance the validator and the parser.
The main issue about input polymorphism is resolving types. Okay, but this issue is solved already at the output types. We can use interface or union to perform polymorph types at output types, but why can't we do that at inputs?
The most of proposals deal with special properties, such as __typename or __inputname, but I think they aren't necessary, because we can use resolveType and isTypeOf methods at interfaces and unions. Using these methods allows developers to implement their own type resolving, and using them should be required as in the regular interfaces and unions.

enum ProductType {
  Water
  Pipe
}

interface ProductInput {
  type: ProductType
  price: Float
}

input WaterInput implements ProductInput {
  capacity: Float
}

input PipeInput implements ProductInput {
  length: Float
}

or

enum ProductType {
  Water
  Pipe
}

input WaterInput {
  type: ProductType
  price: Float
  capacity: Float
}

input PipeInput {
  type: ProductType
  price: Float
  length: Float
}

union ProductInput = WaterInput | PipeInput

Then we should implement resolveType at ProductInput:

resolveType: value => {
  switch (value.type) {
    case 'Water': return WaterInput;
    case 'Pipe': return PipeInput;
    default: return WaterInput;
  }
}

Or we can implement isTypeOf for the children:

isTypeOf: value => value.type === 'Water'

or if we don't want to use type property:

isTypeOf: value => 'capacity' in value

This enhancement won't break the existing syntax and semantic. It only needs to update the validator and the parser. They have to confirm and parse interfaces or unions as inputs, if these type resolver methods are available.
What do you think?
Sorry for opening a new issue, but I think this proposal is different from the others, because it considers this issue more generally.

@leebyron
Copy link
Collaborator

leebyron commented Oct 2, 2018

This is missing painfully and GraphQL really needs this feature.

Could you please elaborate on this? I'm not able to follow your example to understand how the interface type is actually used. Could you share a more realistic example that better illustrates the problem that is limiting and why you think this is the preferable solution over #395 or #488?

@leebyron leebyron added the 💭 Strawman (RFC 0) RFC Stage 0 (See CONTRIBUTING.md) label Oct 2, 2018
@mike-marcacci
Copy link
Contributor

@jayhasyee your concerns resonated with me, so I raised them in #488. However, I did eventually come to the conclusion that spec-class support for disambiguating identifiers are worth the changes. Check out this scenario to see if you agree.

@IvanGoncharov
Copy link
Member

We have begun building a single RFC document for this feature, please see:
https://github.com/graphql/graphql-spec/blob/master/rfcs/InputUnion.md

The goal of this document is to consolidate all related ideas to help move the proposal forward, so we decided to close all overlapping issues including this one.
Please see discussion in #627

If you want to add something to the discussion please feel free to submit PR against the RFC document.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
💭 Strawman (RFC 0) RFC Stage 0 (See CONTRIBUTING.md)
Projects
None yet
Development

No branches or pull requests

4 participants