Skip to content

GraphQL Input Types — Structured Arguments for Mutations and Queries

DodaTech Updated 2026-06-28 3 min read

In this tutorial, you will learn about Graphql Input Types. We cover key concepts, practical examples, and best practices to help you master this topic.

GraphQL input types allow passing complex structured objects as arguments to mutations and queries, enabling multi-field input with validation and nested structures.

What You'll Learn

  • Defining input types with the input keyword
  • Using input types for mutations
  • Creating nested input types

Why It Matters

Without input types, each mutation field would need separate arguments. Input types enable structured, validated, and reusable argument definitions.

Code Examples

# Input type definitions
input CreateUserInput {
  name: String!
  email: String!
  password: String!
  age: Int
  address: AddressInput
}

input UpdateUserInput {
  name: String
  email: String
  age: Int
}

input AddressInput {
  street: String!
  city: String!
  country: String!
  zipCode: String!
}

input PostFilterInput {
  status: PostStatus
  authorId: ID
  createdAfter: DateTime
  createdBefore: DateTime
  tags: [String!]
}

type Mutation {
  createUser(input: CreateUserInput!): User!
  updateUser(id: ID!, input: UpdateUserInput!): User!
  deleteUser(id: ID!): Boolean!
}

type Query {
  posts(filter: PostFilterInput): [Post!]!
}
// Input type validation in resolvers
const resolvers = {
  Mutation: {
    createUser: async (parent, { input }, { dataSources }) => {
      // Input is already validated by GraphQL type system
      // But add business logic validation
      const errors = [];

      if (input.name.length < 2) {
        errors.push('Name must be at least 2 characters');
      }
      if (input.password.length < 8) {
        errors.push('Password must be at least 8 characters');
      }
      if (input.address && !input.address.zipCode) {
        errors.push('Zip code is required with address');
      }

      if (errors.length > 0) {
        throw new UserInputError('Validation failed', { errors });
      }

      return dataSources.userAPI.createUser(input);
    }
  }
};
# Python input types with Strawberry
import strawberry

@strawberry.input
class CreateUserInput:
    name: str
    email: str
    password: str
    age: int | None = None

@strawberry.input
class PostFilter:
    status: PostStatus | None = None
    author_id: str | None = None
    created_after: datetime | None = None

@strawberry.type
class Mutation:
    @strawberry.mutation
    def create_user(self, input: CreateUserInput) -> User:
        return create_user_in_db(input)

Common Mistakes

1. Using Object Types Instead of Input Types

Object types cannot be used as arguments. Always define input types with the input keyword.

2. Making All Input Fields Required

Make fields optional unless truly required. This makes mutations more flexible.

3. Not Reusing Input Types

Define reusable input types. Avoid duplicating field definitions.

4. Creating Mutations Without Input Types

Use input types for all mutations with more than 2-3 arguments.

5. Forgetting Input Type Validation

Add business logic validation in resolvers beyond Type Checking.

Practice Questions

  1. What keyword defines input types?
  2. Why can't object types be used as mutation arguments?
  3. How do you make an input field optional?
  4. Can input types reference other input types?
  5. How do you validate input type fields?

Answers:

  1. input.
  2. Object types may have resolvers; input types are plain data structures.
  3. Omit the ! to make it nullable/optional.
  4. Yes. Input types can have fields of other input types for nested data.
  5. Use GraphQL's type system for type validation and resolver logic for business validation.

Challenge: Design input types for a complete e-commerce checkout system: CheckoutInput (with nested AddressInput, PaymentInput, ShippingInput, LineItemInput). Include validation for each field.

FAQ

Can input types implement interfaces?

No. Input types cannot implement interfaces or unions. They are plain data containers.

Can input types have default values?

Yes. Fields in input types can have default values defined in the schema.

What is the difference between input and argument?

Input types are structured argument definitions. Arguments are individual values passed to a field.

Can I reuse input types across mutations?

Yes. Define common input types and reuse them across multiple mutations.

How do I handle optional nested inputs?

Make the nested input field nullable and check for null in the resolver.

Mini Project

Design input types for a project management API: CreateProjectInput, CreateTaskInput, UpdateTaskInput, TaskFilterInput, and AssigneeInput. Include nested inputs for subtasks, comments, and attachments. Implement validation in resolvers.

What's Next

Deep dive into GraphQL arguments for field-level parameters, then explore directives for schema metadata.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro