Schema

Every GraphQL API has a schema and that is used to define all the functionalities for an API. A schema is defined by passing 3 object types : Query , Mutation and Subscription .

Mutation and Subscription are optional, meanwhile Query has to always be there.

This is an example of a schema defined using Strawberry:

import strawberry
 
 
@strawberry.type
class Query:
    @strawberry.field
    def hello(self) -> str:
        return "Hello World"
 
 
schema = strawberry.Schema(Query)

API reference

class Schema(Query, mutation=None, subscription=None, **kwargs): ...

query: Type

The root query Strawberry type. Usually called Query .

Note

A query type is always required when creating a Schema.

mutation: Optional[Type] = None

The root mutation type. Usually called Mutation .

subscription: Optional[Type] = None

The root subscription type. Usually called Subscription .

config: Optional[StrawberryConfig] = None

Pass a StrawberryConfig object to configure how the schema is generated. Read more .

types: List[Type] = []

List of extra types to register with the Schema that are not directly linked to from the root Query.

Defining extra `types` when using Interfaces
from datetime import date
import strawberry
 
 
@strawberry.interface
class Customer:
    name: str
 
 
@strawberry.type
class Individual(Customer):
    date_of_birth: date
 
 
@strawberry.type
class Company(Customer):
    founded: date
 
 
@strawberry.type
class Query:
    @strawberry.field
    def get_customer(
        self, id: strawberry.ID
    ):  # -> Customer   note we're returning the interface here
        if id == "mark":
            return Individual(name="Mark", date_of_birth=date(1984, 5, 14))
 
        if id == "facebook":
            return Company(name="Facebook", founded=date(2004, 2, 1))
 
 
schema = strawberry.Schema(Query, types=[Individual, Company])

extensions: List[Type[SchemaExtension]] = []

List of extensions to add to your Schema.

scalar_overrides: Optional[Dict[object, ScalarWrapper]] = None

Override the implementation of the built in scalars. More information .


Methods

.execute() (async)

Executes a GraphQL operation against a schema (async)

async def execute(
    query, variable_values, context_value, root_value, operation_name
): ...

query: str

The GraphQL document to be executed.

variable_values: Optional[Dict[str, Any]] = None

The variables for this operation.

context_value: Optional[Any] = None

The value of the context that will be passed down to resolvers.

root_value: Optional[Any] = None

The value for the root value that will passed to root resolvers.

operation_name: Optional[str] = None

The name of the operation you want to execute, useful when sending a document with multiple operations. If no operation_name is specified the first operation in the document will be executed.

.execute_sync()

Executes a GraphQL operation against a schema

def execute_sync(query, variable_values, context_value, root_value, operation_name): ...

query: str

The GraphQL document to be executed.

variable_values: Optional[Dict[str, Any]] = None

The variables for this operation.

context_value: Optional[Any] = None

The value of the context that will be passed down to resolvers.

root_value: Optional[Any] = None

The value for the root value that will passed to root resolvers.

operation_name: Optional[str] = None

The name of the operation you want to execute, useful when sending a document with multiple operations. If no operation_name is specified the first operation in the document will be executed.


Handling execution errors

By default Strawberry will log any errors encountered during a query execution to a strawberry.execution logger. This behaviour can be changed by overriding the process_errors function on the strawberry.Schema class.

The default functionality looks like this:

# strawberry/schema/base.py
from strawberry.types import ExecutionContext
 
logger = logging.getLogger("strawberry.execution")
 
 
class BaseSchema:
    ...
 
    def process_errors(
        self,
        errors: List[GraphQLError],
        execution_context: Optional[ExecutionContext] = None,
    ) -> None:
        for error in errors:
            StrawberryLogger.error(error, execution_context)
# strawberry/utils/logging.py
from strawberry.types import ExecutionContext
 
 
class StrawberryLogger:
    logger: Final[logging.Logger] = logging.getLogger("strawberry.execution")
 
    @classmethod
    def error(
        cls,
        error: GraphQLError,
        execution_context: Optional[ExecutionContext] = None,
        # https://www.python.org/dev/peps/pep-0484/#arbitrary-argument-lists-and-default-argument-values
        **logger_kwargs: Any,
    ) -> None:
        # "stack_info" is a boolean; check for None explicitly
        if logger_kwargs.get("stack_info") is None:
            logger_kwargs["stack_info"] = True
 
        logger_kwargs["stacklevel"] = 3
 
        cls.logger.error(error, exc_info=error.original_error, **logger_kwargs)

Filtering/customising fields

You can customise the fields that are exposed on a schema by subclassing the Schema class and overriding the get_fields method, for example you can use this to create different GraphQL APIs, such as a public and an internal API. Here’s an example of this:

@strawberry.type
class User:
    name: str
    email: str = strawberry.field(metadata={"tags": ["internal"]})
 
 
@strawberry.type
class Query:
    user: User
 
 
def public_field_filter(field: StrawberryField) -> bool:
    return "internal" not in field.metadata.get("tags", [])
 
 
class PublicSchema(strawberry.Schema):
    def get_fields(
        self, type_definition: StrawberryObjectDefinition
    ) -> List[StrawberryField]:
        return list(filter(public_field_filter, type_definition.fields))
 
 
schema = PublicSchema(query=Query)
Note

The get_fields method is only called once when creating the schema, this is not intended to be used to dynamically customise the schema.

Edit this page on GitHub