samsarahq/thunder

Support GraphQL Interfaces / Union Types

stephen opened this issue · 4 comments

Some ideas:

interfaces

  • golang interfaces, with some annotation for SDL/field funcs

union types

  • one-hot struct

union types

Add a special embed tag for unions that hints to the schemabuilder that this is a one-hot struct.

type GatewayUnion struct {
  *graphql.Union

  // Each must be anonymous, must be pointer type
  *models.Gateway
  *models.Vehicle
}

object.FieldFunc("gateways", func(...) ([]*GatewayUnion, error) {
  ags := models.AssetGateway.Fetch(ctx)
  if err != nil {
    return nil, err 
  }
  vgs := models.VehicleGateway.Fetch(ctx)
  if err != nil {
    return nil, err 
  }
  
  results := make([]*GatewayUnion, 0, len(ags)+len(vgs))
  for _, ag := range ags {
    results = append(results, &GatewayUnion{AssetGateway: ag})
  }

  for _, vg := range vgs {
    results = append(results, &GatewayUnion{VehicleGateway: vg})
  }
  return results, nil
})

Fields that return a union should be expected to only ever return one of the hot values. It will panic if that fails.

proposal

schemabuilder:

  • Add reflect for graphql.Union embedded types
  • In extracting union return types during resolution, verify one-hotness.

executor:

  • add support for union type in big switch, use On field on Fragment

introspection:

  • add support

Hi, we have been looking at this project and find its approach quite interesting. We needed support for interfaces and added this in a fork. Would you be interested in a PR?

@magiconair is this fork with interface support public and/or has there been a pull request for it into thunder yet?