Skip to content

Input polymorphism #415

Closed
Closed
@hasyee

Description

@hasyee

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions