Search code examples
apolloapollo-client

graphql query with different output


I have an api with an endpoint which can takes different query parameters. /toto?number=&shipments.tracking_number=&customer.email=. The thing is that to get the query, I'm using only one input on the frontend and depending on that input, I have to fill the corresponding query parameter. But, depending on the query the user is passing, the JSON I receive in response is different. For example if he provides his email, the duplicates field won't be present in the response or if he provides a tracking number, the total won't be there either. Is there a way to make a query that is dynamic to handle if a field is in the response or not ?

export const GET_ORDER = gql`
  query GetOrder($query: String!) {
    getOrder(query: $query) {
      id
      tokenValue
      number
      total
      duplicates
      shippingTotal
  }
}`

Solution

  • You can do this with two subtypes as an example using unions and interfaces, you can easily extend to additional ones.

    In your typeDefs:

    interface CoreOrder {
      id: ID!
      tokenValue: String!
      number: Int!
      shippingTotal: Float!
    }
    
    Type Order1 implements CoreOrder {
      id: ID!
      tokenValue: String!
      number: Int!
      shippingTotal: Float!
      total: Float!
    }
    
    Type Order2 implements CoreOrder {
      id: ID!
      tokenValue: String!
      number: Int!
      shippingTotal: Float!
      duplicates: Int!
    }
    
    union Order = Order1 | Order 2
    

    Now your query can be defined to return whichever fields are appropriate:

    query GetOrder($query: String!) {
      getOrder(query: $query) {
        __typename
        id
        tokenValue
        number
        shippingTotal
        ... on Order1 {
          total
        }
        ... on Order2 {
          duplicates
        }
      }
    }
    

    You'll need to implement:

    1. a __resolveType resolver that figures out what type your query is returning
    2. resolvers for CoreOrder to handle those 4 fields
    3. an Order1 resolver for the total field
    4. an Order2 resolver for the duplicates field

    Your GraphQL server will then figure out which resolvers to call and in what order and package up the results for your client.