# Single vs. Multiple Mutations for Serial Workflow

**URL:** <https://community.apollographql.com/t/single-vs-multiple-mutations-for-serial-workflow/9504>\
**Category:** Schema Design\
**Tags:** schema-design\
**Created:** [October 15, 2025, 4:42pm UTC](https://community.apollographql.com/t/single-vs-multiple-mutations-for-serial-workflow/9504 "2025-10-15T16:42:53Z")\
**Posts on this page:** 1\
**Showing post:** 3

<div class="post-metadata">

**Author:** ![michaeldouglasdev](https://sea1.discourse-cdn.com/flex019/user_avatar/community.apollographql.com/michaeldouglasdev/32/4911_2.png) [@michaeldouglasdev](https://community.apollographql.com/u/michaeldouglasdev)\
**Post date:** [October 18, 2025, 8:58pm UTC](https://community.apollographql.com/t/single-vs-multiple-mutations-for-serial-workflow/9504/3 "2025-10-18T20:58:03Z")

</div>

Hello Tyler!

Good to talk to you again.

A while ago, I was thinking exactly the same way about grouping mutations to reduce the number of requests.

For example, imagine having both `createUser` and `login` mutation fields.  
Obviously, `createUser` could return a JWT token, but that would give it an extra responsibility, and conceptually, creating a user should only handle user creation, not authentication.

As you mentioned, mutations are executed sequentially when defined at the root level.  
However, when fields are nested, they are executed in parallel.

In my case, I also had a namespace-based structure, and to deal with sequential vs. parallel execution, I had to use aliases for the namespaces.

One interesting behavior I noticed was this:  
when the user creation succeeds, the login works fine.  
When the `createUser` field throws an error using `throw new GraphQLError`, the `login` field is not called, which is the expected behavior.  
However, when using a type-based error handling approach, the `login` field is always executed, since the previous field (`createUser`) didn’t actually throw, even though it failed logically.  
This happens both when using a `success: Boolean!` flag or when modeling responses with a union type.

I had tried to create a directive called `@dependsOn(requires: "")` to reduce the number of requests, but no success.  
Check out my idea:

```auto
mutation CreateAndLoginMutation(
  $loginInput: LoginInput!
  $createUserInput: CreateUserInput!
) {
  accountsCreate: accounts {
    createUser(input: $createUserInput) {
      __typename
      ... on User {
        id
        name
        email
      }
      ... on EmailIsAlreadyTakenError {
        message
        code
      }
      ... on GenericError {
        message
        code
      }
    }
  }

  accountsLogin: accounts {
    login(input: $loginInput) @dependsOn(requires: "accountsCreate.createUser.__typename === 'User'") {
      __typename
      ... on Auth {
        token
        user {
          id
          name
          email
        }
      }
      ... on InvalidCredentialsError {
        message
      }
      ... on GenericError {
        message
      }
    }
  }
}

```

I think I’ll try again, but using Apollo Plugins, @graphql-tools/utils (mapSchema) and metadata, just like I did in the previous topic

> [@Input argument validation](https://community.apollographql.com/t/input-argument-validation/8672/22):
>
> I’m back with updates! My previous implementation wasn’t working quite as expected, especially with nested fields. In those cases, the parent resolver was executed before input validation occurred in the nested fields, which wasn’t ideal for me. I want to validate all inputs first, regardless of whether they’re placed in nested fields or at the root, and only then execute the resolvers. After experimenting, I found a better approach: I’m still using mapSchema to attach metadata, and I moved t…

---

_[View the full topic](https://community.apollographql.com/t/single-vs-multiple-mutations-for-serial-workflow/9504)._
