Graphql-js: GraphQLList in UnionType

Created on 15 Dec 2016  路  6Comments  路  Source: graphql/graphql-js

Why cant I use GraphQLList(ObjectType) in UnionTypes

const UserType = new GraphQLUnionType({
    name: "User",
    types: [new GraphQLList(CustomerType), new GraphQLList(EmployeeType)],
    resolveType: (obj, args, context) =>{
        if(obj[0].userType == "CUST"){
            return new GraphQLList(CustomerType)
        }
        if(obj[0].userType == "EMP"){
            return new GraphQLList(EmployeeType)
        }
    }
});

Error: UserType may only contain Object types, it cannot contain: [CustomerType].

I dont want use new GraphQLList(UserType) since this would mean it wouldresolveType for each iteration

Most helpful comment

What if you could make a union of list types but only if both were also list types?

Hm, wouldn't that be functionally equivalent to a list of union type? e.g.

union UnionOfListOfFooBar = [Foo] | [Bar]
type Thing {
  field: UnionOfListOfFooBar
}

can't be done today, but:

union UnionOfFooBar = Foo | bar
type Thing {
  field: [UnionOfFooBar]
}

can?

All 6 comments

This is working as expected, as far as I can see: https://facebook.github.io/graphql/#sec-Unions

GraphQL Unions represent an object that could be one of a list of GraphQL Object types

Since a GraphQLList is not an object type, you can't put it in a union.

Is there any particular reason why only Object Types are allowed in UnionType types?

Is there any particular reason why only Object Types are allowed in UnionType types?

So I don't think we ran into a use case where we needed a list in a union, which is why I suspect our starting position when developing the spec was probably to disallow it.

When I think about potential complexity from allowing it: allowing lists inside unions could make things trickier for client-side parsers/models, as depending on which union type was returned, you would either get an array or an object. In particular, if I had a union that returned either Foo or [Bar], my parser would have to handle either seeing an object or an array. Additionally, in a language without union types, I might want to generate a marker interface for the union, but it's not clear how to make List<Bar> implement a marker interface if we're using a standard language List construct. So there's definitely some additional complexity that comes from allowing a list inside a union.

The question for me then becomes whether there's a clean workaround; it seems like there is, because in the example above, I could have made a union of Foo and BarsObject, where BarsObject has a single field bars that returns [Bar]. That's not perfect, but it's also not too bad of a workaround.

Hope this helps!

Yeah I definitely think it's convenient that a specific field is always either a list or not a list.

What if you could make a union of list types but only if both were also list types?

What if you could make a union of list types but only if both were also list types?

Hm, wouldn't that be functionally equivalent to a list of union type? e.g.

union UnionOfListOfFooBar = [Foo] | [Bar]
type Thing {
  field: UnionOfListOfFooBar
}

can't be done today, but:

union UnionOfFooBar = Foo | bar
type Thing {
  field: [UnionOfFooBar]
}

can?

From the client's point of view, yes - I suppose it would just be a convenience thing for the server. Looks like that's what the OP would be looking for. I don't have an opinion on it, just adding an extra option.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

galki picture galki  路  3Comments

sudheerj picture sudheerj  路  3Comments

itajaja picture itajaja  路  3Comments

davide-ganito picture davide-ganito  路  4Comments

henry74 picture henry74  路  4Comments