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).
-
Queryis the entry point for all the query operations -
Mutationis the entry point for all the mutations -
Subscriptionis the entry point for all the subscriptions.
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: inttype 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: Charactertype Character {
name: String!
age: Int!
}
type Book {
title: String!
mainCharacter: Character!
}Object types can subclass other object types to reuse their fields, as long as the subclass is decorated too:
import strawberry
@strawberry.type
class Character:
name: str
age: int
@strawberry.type
class Wizard(Character):
house: strtype Character {
name: String!
age: Int!
}
type Wizard {
name: String!
age: Int!
house: String!
}An undecorated subclass would be published as its parent type, without its own fields, so Strawberry raises an error when one is used in the schema. The same applies to input types and interfaces.
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.11 through 3.13, Strawberry can only read the strawberry.field()
options when it can evaluate the annotation when the type is created. When the
field type is defined further down the module, or only imported under
TYPE_CHECKING , pass the options as the field’s default
(account: Account = strawberry.field(...) ), define the type first, or use
strawberry.lazy() for it, which 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"),
] Otherwise Strawberry raises an
UnresolvedStrawberryFieldError
when the type is created, instead of ignoring options like permissions. Python
3.14 and newer read the options 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.