make graphql mutation return multiple types

476 Views Asked by At

i'm working on creating mutations for a project i'm working on but stuck on the resolver returns, i won't to handle the errors while i'm at it as well by sending back messages for notifications to make it user friendly, but let's say my mutation is UPDATE_USER and it should also return the updated user instance, how can i set my mutation to double returns if possible?

that's how it looks

export const UPDATE_USER = {
    type: UserType,
    args: {
        user_id: {type: GraphQLString}!,
        first_name: {type: GraphQLString}!,
        last_name: {type: GraphQLString},

but i want something like this incase there's no user like the update failed for some reason

export const UPDATE_USER = {
    type: UserType|| MessageType,
    args: {
        user_id: {type: GraphQLString}!,
        first_name: {type: GraphQLString}!,
        last_name: {type: GraphQLString},

but i can't find a way to make it work

1

There are 1 best solutions below

1
Jimmy Kurian On

In GraphQL, you can't directly return multiple types from a single field, but you can create a wrapper type that can contain either the user or the error message. This is often called a "union type" or an "interface type".

Here's how you can define a union type for this purpose:

union UserResult = UserType | MessageType

Then, you can use this UserResult type in your UPDATE_USER mutation:

export const UPDATE_USER = {
    type: UserResult,
    args: {
        user_id: {type: GraphQLString},
        first_name: {type: GraphQLString},
        last_name: {type: GraphQLString},
    },
    resolve: async (parent, args, context, info) => {
        // Your logic here
        if (errorCondition) {
            return {
                __typename: "MessageType",
                message: "An error occurred",
            };
        } else {
            return {
                __typename: "UserType",
                // ...user fields
            };
        }
    }
};

In the resolver, you can specify which type you are returning by setting the __typename field. The client can then use inline fragments to handle the different types:

mutation {
  updateUser(user_id: "1", first_name: "John", last_name: "Doe") {
    __typename
    ... on UserType {
      user_id
      first_name
      last_name
    }
    ... on MessageType {
      message
    }
  }
}

This way, you can return either a UserType or a MessageType from your UPDATE_USER mutation, and the client can handle both cases.