Object types

Object types are the fundamentals of any GraphQL schema, they are used to define the kind of objects that exist in a schema. Object types are created by defining a name and a list of fields, here’s an example object type defined using the GraphQL schema language:

type Character {
  name: String!
  age: Int!
}

A note on Query, Mutation and Subscription

While reading about GraphQL you might have encountered 3 special object types: Query , Mutation and Subscription . They are defined as standard object types, with the difference that they are also used as entry points for your schema (also referred as root types).

For a walk-through on how to define schemas, read the schema basics .

Defining object types

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

import strawberry
 
 
@strawberry.type
class Character:
    name: str
    age: int
type Character {
  name: String!
  age: int!
}

You can also refer to other types, like this:

import strawberry
 
 
@strawberry.type
class Character:
    name: str
    age: int
 
 
@strawberry.type
class Book:
    title: str
    main_character: Character
type Character {
  name: String!
  age: Int!
}
 
type Book {
  title: String!
  mainCharacter: Character!
}

Customizing fields with Annotated

You can configure fields by adding strawberry.field() to typing.Annotated . This syntax works on object types, input types, and interfaces, including when using from __future__ import annotations :

from typing import Annotated
 
import strawberry
 
 
@strawberry.type
class User:
    name: Annotated[
        str,
        strawberry.field(name="displayName", description="The displayed name"),
    ]
    tags: Annotated[list[str], strawberry.field(default_factory=list)]

All strawberry.field() options are supported. In particular, default and default_factory also configure the generated dataclass constructor, so User(name="Patrick") in the example above gets a new empty tags list.

On Python 3.10 through 3.13, use strawberry.lazy() when the field type is only imported under TYPE_CHECKING or otherwise unavailable at runtime. This form works together with field metadata:

from typing import TYPE_CHECKING, Annotated
 
import strawberry
 
if TYPE_CHECKING:
    from .users import User
 
 
@strawberry.type
class Post:
    author: Annotated[
        "User",
        strawberry.lazy(".users"),
        strawberry.field(description="The post author"),
    ]

Python 3.14 and newer can also preserve the field metadata on a direct unresolved reference without strawberry.lazy() .

The field configuration can be combined with other Strawberry metadata. The order of the metadata does not matter:

@strawberry.type
class Query:
    result: Annotated[
        Success | Failure,
        strawberry.union("Result"),
        strawberry.field(description="The operation result"),
    ]

Use only one strawberry.field() for each field. You can alternatively use the equivalent assignment syntax, such as name: str = strawberry.field(description="The displayed name") .

strawberry.field() must be metadata on the field’s outermost Annotated type. Placing it inside a wrapper configures no GraphQL field, so Strawberry raises an error instead of silently ignoring it:

# Incorrect: strawberry.field() describes the list item, not `names`.
names: list[Annotated[str, strawberry.field(description="A name")]]
 
# Correct: strawberry.field() describes `names`.
names: Annotated[list[str], strawberry.field(description="The names")]

API

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

Creates an object type from a class definition.

name : if set this will be the GraphQL name, otherwise the GraphQL will be generated by camel-casing the name of the class.

description : this is the GraphQL description that will be returned when introspecting the schema or when navigating the schema using GraphiQL.

Edit this page on GitHub