Resolvers
When defining a GraphQL schema, you usually start with the definition of the schema for your API, for example, letβs take a look at this schema:
import strawberry
@strawberry.typeclass User: name: str
@strawberry.typeclass Query: last_user: User
type User { name: String!}
type Query { lastUser: User!}
We have defined a User
type and a Query
type. Next, to define how the data
is returned from our server, we will attach resolvers to our fields.
Letβs define a resolver
Letβs create a resolver and attach it to the lastUser
field. A resolver is a
Python function that returns data. In Strawberry there are two ways of defining
resolvers; the first is to pass a function to the field definition, like this:
def get_last_user() -> User: return User(name="Marco")
@strawberry.typeclass Query: last_user: User = strawberry.field(resolver=get_last_user)
Now when Strawberry executes the following query, it will call the
get_last_user
function to fetch the data for the lastUser
field:
{ lastUser { name }}
{ "data": { "lastUser": { "name": "Marco" } }}
Defining resolvers as methods
The other way to define a resolver is to use strawberry.field
as a decorator,
like here:
@strawberry.typeclass Query: @strawberry.field def last_user(self) -> User: return User(name="Marco")
This is useful when you want to co-locate resolvers and types or when you have very small resolvers.
If youβre curious how the self
parameter works in the resolver, you can read
more about it in the
accessing parent data guide .
Defining arguments
Fields can also have arguments; in Strawberry the arguments for a field are defined on the resolver, as you would normally do in a Python function. Letβs define a field on a Query that returns a user by ID:
import strawberry
@strawberry.typeclass User: name: str
@strawberry.typeclass Query: @strawberry.field def user(self, id: strawberry.ID) -> User: # here you'd use the `id` to get the user from the database return User(name="Marco")
type User { name: String!}
type Query { user(id: ID!): User!}
Optional arguments
Optional or nullable arguments can be expressed using Optional
. If you need to
differentiate between null
(maps to None
in Python) and no arguments being
passed, you can use UNSET
:
from typing import Optionalimport strawberry
@strawberry.typeclass Query: @strawberry.field def hello(self, name: Optional[str] = None) -> str: if name is None: return "Hello world!" return f"Hello {name}!"
@strawberry.field def greet(self, name: Optional[str] = strawberry.UNSET) -> str: if name is strawberry.UNSET: return "Name was not set!" if name is None: return "Name was null!" return f"Hello {name}!"
type Query { hello(name: String = null): String! greet(name: String): String!}
Like this you will get the following responses:
{ unset: greet null: greet(name: null) name: greet(name: "Dominique")}
{ "data": { "unset": "Name was not set!", "null": "Name was null!", "name": "Hello Dominique!" }}
Accessing execution information
Sometimes it is useful to access the information for the current execution
context. Strawberry allows to declare a parameter of type Info
that will be
automatically passed to the resolver. This parameter contains the information
for the current execution context.
import strawberryfrom strawberry.types import Info
def full_name(root: "User", info: strawberry.Info) -> str: return f"{root.first_name} {root.last_name} {info.field_name}"
@strawberry.typeclass User: first_name: str last_name: str full_name: str = strawberry.field(resolver=full_name)
You donβt have to call this parameter info
, its name can be anything.
Strawberry uses the type to pass the correct value to the resolver.
API
Info objects contain information for the current execution context:
class Info(Generic[ContextType, RootValueType])
Parameter name | Type | Description |
---|---|---|
field_name | str | The name of the current field (generally camel-cased) |
python_name | str | The βPython nameβ of the field (generally snake-cased) |
context | ContextType | The value of the context |
root_value | RootValueType | The value for the root type |
variable_values | Dict[str, Any] | The variables for this operation |
operation | OperationDefinitionNode | The ast for the current operation (public API might change in future) |
path | Path | The path for the current field |
selected_fields | List[SelectedField] | Additional information related to the current field |
schema | Schema | The Strawberry schema instance |