Input Object Types

GraphQL input object types let you pass structured data as arguments. While scalar arguments work for simple values, input types let you group related fields into a single object. Input types differ from output object types: their fields cannot have arguments and they use the input keyword in the schema.

GraphQL schema

GraphQL
input CreateBookInput {
  title: String!
  author: String!
}

type Mutation {
  createBook(input: CreateBookInput!): Book
}

Defining an Input Type#

Any C# class or record used as a resolver parameter (that is not a scalar, enum, or service) becomes an input object type in the schema.

Using Records and Immutable Types#

Input types can use immutable classes or C# records. Hot Chocolate calls the constructor instead of setting properties. The rules are:

  1. Each constructor parameter type must match the corresponding property type.
  2. Each constructor parameter name must match the property name (with a lowercase first letter).
  3. All properties must have a matching constructor parameter.

Hot Chocolate validates input constructors at schema build time, so mismatches are caught early.

C#
public record CreateBookInput(string Title, string Author);

This record is equivalent to a class with a constructor and get-only properties.

Default Values#

The [DefaultValue] attribute assigns a default value to an input field. When the client omits the field, the default is used.

Default values maintain backward compatibility. When you add a new field to an input type, providing a default value keeps existing queries working.

Default Values with GraphQL Syntax#

For complex defaults (objects or lists), use [DefaultValueSyntax] with GraphQL value literal syntax.

C#
public class UserProfileInput
{
    public string? Name { get; set; }

    [DefaultValueSyntax("{ notifications: true, theme: \"light\" }")]
    public Preferences? Preferences { get; set; }
}

In code-first, use the DefaultValueSyntax method:

C#
descriptor
    .Field(f => f.Preferences)
    .DefaultValueSyntax("{ notifications: true, theme: \"light\" }");

Optional Properties#

Use Optional<T> to distinguish between a field that was not provided and a field explicitly set to null. This is important for partial updates where you need to know whether the client intended to clear a value.

C#
public class UpdateBookInput
{
    [DefaultValue("")]
    public Optional<string> Title { get; set; }

    public string Author { get; set; }
}

When using Optional<T> on a non-nullable field, you must add [DefaultValue] to make the field optional in the schema.

Records work too:

C#
public record UpdateBookInput(
    [property: DefaultValue("")] Optional<string> Title,
    string Author);

OneOf Input Objects#

A @oneOf input type requires that exactly one field is set and non-null. This provides input polymorphism, letting a single argument accept different shapes of data.

GraphQL schema

GraphQL
input PetInput @oneOf {
  cat: CatInput
  dog: DogInput
}

All fields on a @oneOf input must be nullable. Hot Chocolate validates at runtime that exactly one field is provided.

Next Steps#

Edit this page on GitHub
Last updated on by Tobias Tengler