Input types

In addition to object types GraphQL also supports input types. While being similar to object types, they are better suited for input data as they limit the kind of types you can use for fields.

This is how the GraphQL spec defines the difference between object types and input types :

The GraphQL Object type (ObjectTypeDefinition)… is inappropriate for re‐use (as input), because Object types can contain fields that define arguments or contain references to interfaces and unions, neither of which is appropriate for use as an input argument. For this reason, input objects have a separate type in the system.

Defining input types

In Strawberry, you can define input types by using the @strawberry.input decorator, like this:

import strawberry
 
 
@strawberry.input
class Point2D:
    x: float
    y: float
input Point2D {
  x: Float!
  y: Float!
}

Then you can use input types as argument for your fields or mutations:

import strawberry
 
 
@strawberry.type
class Mutation:
    @strawberry.mutation
    def store_point(self, a: Point2D) -> bool:
        return True

If you want to include optional arguments, you need to provide them with a default. For example if we want to expand on the above example to allow optional labeling of our point we could do:

import strawberry
from typing import Optional
 
 
@strawberry.input
class Point2D:
    x: float
    y: float
    label: Optional[str] = None
type Point2D {
    x: Float!
    y: Float!
    label: String = null
}

When you need to distinguish between a field being set to null versus being completely absent (common in update operations), you can use strawberry.Maybe . See the Maybe documentation for comprehensive examples and usage patterns.

Input types only hold the values sent by the client, so their fields can’t have resolvers. Strawberry raises an error when an input type has a field with a resolver, including one inherited from an output type.

Input instances as default values

An input type instance can be used as the default value of a resolver argument or of another input’s field. The default is printed in the schema, reported by introspection, and each execution receives a fresh instance:

import strawberry
 
 
@strawberry.input
class Pagination:
    limit: int = 10
    offset: int = 0
 
 
@strawberry.input
class Filters:
    query: str
    pagination: Pagination = strawberry.field(default_factory=Pagination)
 
 
@strawberry.type
class Query:
    @strawberry.field
    def search(self, filters: Filters = Filters(query="")) -> list[str]:
        return []
input Pagination {
  limit: Int! = 10
  offset: Int! = 0
}
 
input Filters {
  query: String!
  pagination: Pagination! = { limit: 10, offset: 0 }
}
 
type Query {
  search(
    filters: Filters! = { query: "", pagination: { limit: 10, offset: 0 } }
  ): [String!]!
}

API

@strawberry.input(name: str = None, description: str = None)

Creates an input type from a class definition.

One Of Input Types

Strawberry also supports defining input types that can have only one field set. This is based on the OneOf Input Objects RFC

To define a one of input type you can use the one_of flag on the @strawberry.input decorator:

import strawberry
 
 
@strawberry.input(one_of=True)
class SearchBy:
    name: str | None
    email: str | None
input SearchBy @oneOf {
  name: String
  email: String
}

Clients set exactly one field, which can’t be null , and Strawberry sets the other fields to None .

Note

GraphQL requires the fields of a OneOf input to be nullable and without a default value, so Strawberry raises an error when the schema is built if one of them is required or has a default, like name: str | None = None .

Fields declared with strawberry.Maybe work too, but as OneOf fields can’t be set to null , the Some wrapper doesn’t add anything here.

Deprecating fields

Fields can be deprecated using the argument deprecation_reason .

Note

This does not prevent the field from being used, it’s only for documentation. See: GraphQL field deprecation .

import strawberry
from typing import Optional
 
 
@strawberry.input
class Point2D:
    x: float
    y: float
    z: Optional[float] = strawberry.field(
        deprecation_reason="3D coordinates are deprecated"
    )
    label: Optional[str] = None
input Point2D {
  x: Float!
  y: Float!
  z: Float @deprecated(reason: "3D coordinates are deprecated")
  label: String = null
}
Edit this page on GitHub