graphql_ppx icon indicating copy to clipboard operation
graphql_ppx copied to clipboard

Unions are not supported for mutation return query type?

Open elnygren opened this issue 5 years ago • 4 comments

I'm getting some errors in a case where my schema has a mutation that returns a union (either the created type or validation errors).

Basically I think it would be a nice pattern to make input validation errors a part of my schema for additional type safety :)

Here's some pseudocode example (unfortunately no time to make exact reprod / can't share code from my own project)

EDIT: I added ...some fields here... below as it was causing confusion, I'm indeed not using empty GraphQL types! schema

type Foo { ...some fields here... }
type FooValidationErrors { ...some fields here... }
union FooResult = Foo | FooValidationErrors
input FooInput {...some fields here...}

type Mutation {
  createFoo(input: FooInput): FooResult
}

query

mutation createFoo {
  createFoo($input: FooInput) {
    ...on Foo {...some fields here...}
    ...on FooValidationErrors {...some fields here...}
  }
}

error: Schema.Invalid_type("Type FooResult doesn't have any fields")

Note: I'm not having any problems using this schema with Apollo server and Apollo client. Just with graphql ppx.

Edit: I decided to alter my schema a bit and went with https://github.com/mhallin/graphql_ppx#non-union-variant-conversion

elnygren avatar Mar 21 '19 18:03 elnygren

I think the problem is your schema which is not valid. As far as I know, you cannot have empty objects or scalar unions. You have no fields in Foo or FooValidationErrors thus you're not querying any fields in mutation response.

The following example which is almost the same as yours would be valid.

Schema:

type Foo {
  id: String!
  name: String!
}

enum UserValidationError {
  SomeError
}

type UserValidationErrors {
  errors: [SomeError!]!
}

union FooResult = Foo | FooValidationErrors

input FooInput {
  name: String
}

type Mutation {
  createFoo(input: FooInput): FooResult
}

Query:

mutation createFoo($input:  FooInput) {
  createFoo(input: $input) {
    ...on Foo {
       id # at least one field required
    }
    ...on FooValidationErrors {
      errors
    }
  }
}

baransu avatar Apr 03 '19 21:04 baransu

@elnygren As you mentioned, the best approach would be to use @bsVariants described in https://github.com/mhallin/graphql_ppx#non-union-variant-conversion

Can this issue be closed?

baransu avatar Apr 03 '19 21:04 baransu

@baransu ah my example was a bit short...

You have no fields in Foo or FooValidationErrors thus you're not querying any fields in mutation response.

This is incorrect, I was just lazy and left them out... (I've fixed this now in the original post).

So in other words: the error happens with a valid schema as I described.

elnygren avatar Apr 04 '19 16:04 elnygren

Could you provide example? Error message says: FooResult doesn’t have any fields so I’m curious 🤔

baransu avatar Apr 05 '19 08:04 baransu