Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GraphQL - Using same field names in different types within union

Tags:

graphql

If I have a union type like this:

union AllOnboardingQuestionTypes = StepFinal | TimeRangesQuestion | PercentQuestion | SingleSelectQuestion | MultiSelectQuestion | InformationOnly

where some of the types have the same field names but different types (e.g. answer for PercentAnswer is float whereas SingleSelect's answer is a string), is this the right way to do the query?

query OnboardingQuestionsQuery {
     onboardingQuestions {
       ... on InformationOnly {
         title
         description
         questionID
         inputType
       }
       ... on StepFinal {
          title
          description
       }
       ... on TimeRangesQuestion {
          title
          description
          timePeriods {
            timePeriod
            estimatedEnd
            estimatedStart
          }
       }
       ... on SingleSelectQuestion {
         title
         description
         questionID
         inputType
         singleSelectAnswer: answer
         singleSelectOptions: options {
           value
           label
         }
       }
       ... on MultiSelectQuestion {
         title
         description
         questionID
         inputType
         multiSelectAnswer: answer
         multiSelectOptions: options
       }
       ... on PercentQuestion {
         title
         description
         questionID
         inputType
         percentAnswer: answer
         min
         max
       }
    }
}

The aliases seem cumbersome to me and will make things tricky as I'll have to dealias when mutating data my hope was that I could just use answer instead of singleSelectAnswer.

But when I try that, I get this error:

{"errors":[{"message":"Fields \"answer\" conflict because they return conflicting types String! and [Boolean!]!. Use different aliases on the fields to fetch both if this was intentional.","locations":[{"line":64,"column":7},{"line":69,"column":7}]},{"message":"Fields \"answer\" conflict because they return conflicting types String! and Float!. Use different aliases on the fields to fetch both if this was intentional.","locations":[{"line":64,"column":7},{"line":74,"column":7}]},{"message":"Fields \"answer\" conflict because they return conflicting types [Boolean!]! and Float!. Use different aliases on the fields to fetch both if this was intentional.","locations":[{"line":69,"column":7},{"line":74,"column":7}]}]}

I'm new to GraphQL and don't know if this is the correct way to handle it. In my head I was hoping to follow a polymorphism approach but maybe that's not the way it's done.

like image 564
jeznag Avatar asked May 25 '17 00:05

jeznag


2 Answers

is this the right way to do the query?

Yes. Unions are restricted in this way according to the current (June2018) GraphQL specification. See also a corresponding issue on graphql.js

The aliases seem cumbersome

The best way to avoid this is for the schema to specify different field names when the return types differ.

like image 176
Stephen Spalding Avatar answered Sep 22 '22 09:09

Stephen Spalding


I had the same problem and find three different solutions to it:

  1. Using Interface
  2. Using Union
  3. Using a String with additional type information

All not very nice but working. I put a simple example project with all solutions on Github: https://github.com/chnoack/apollo-dynamic-types-example

like image 37
Christian Noack Avatar answered Sep 22 '22 09:09

Christian Noack