Back to Strawberry

Schema Directives

docs/types/schema-directives.md

0.327.04.0 KB
Original Source

Schema Directives

Strawberry supports schema directives, which are directives that don't change the behavior of your GraphQL schema but instead provide a way to add additional metadata to it.

For example our Apollo Federation integration is based on schema directives.

Let's see how you can implement a schema directive in Strawberry, here we are creating a directive called keys that can be applied to Object types definitions and accepts one parameter called fields. Note that directive names, by default, are converted to camelCase on the GraphQL schema.

Here's how we can use it in our schema:

python
import strawberry
from strawberry.schema_directive import Location


@strawberry.schema_directive(locations=[Location.OBJECT])
class Keys:
    fields: str


from .directives import Keys


@strawberry.type(directives=[Keys(fields="id")])
class User:
    id: strawberry.ID
    name: str

This will result in the following schema:

graphql
type User @keys(fields: "id") {
  id: ID!
  name: String!
}

Introspection

Directives attached to a Strawberry schema are included in standard GraphQL introspection. Tools can discover their descriptions, arguments, default values, locations, and repeatability with a query such as:

graphql
{
  __schema {
    directives {
      name
      description
      locations
      isRepeatable
      args {
        name
        defaultValue
      }
    }
  }
}

Input objects, enums, and scalars used only by directive arguments are also part of the runtime schema. Their GraphQL names must therefore be distinct from other types in the schema. Directive names must likewise be unique and cannot replace built-in directives such as @skip or @deprecated. Compatible legacy @oneOf definitions use GraphQL's built-in directive automatically.

Directive argument annotations are resolved when the schema is built, in the same way as field and argument annotations elsewhere in the schema. Types imported only under TYPE_CHECKING should use strawberry.lazy so Strawberry can resolve them at runtime.

Overriding field names

You can use strawberry.directive_field to override the name of a field:

python
@strawberry.schema_directive(locations=[Location.OBJECT])
class Keys:
    fields: str = strawberry.directive_field(name="as")

Locations

Schema directives can be applied to many different parts of a schema. Here's the list of all the allowed locations:

NameDescription
SCHEMAstrawberry.SchemaThe definition of a schema
SCALARstrawberry.scalarThe definition of a scalar
OBJECTstrawberry.typeThe definition of an object type
FIELD_DEFINITIONstrawberry.fieldThe definition of a field on an object type or interface
ARGUMENT_DEFINITIONstrawberry.argumentThe definition of an argument
INTERFACEstrawberry.interfaceThe definition of an interface
UNIONstrawberry.unionThe definition of an union
ENUMstrawberry.enumThe definition of a enum
ENUM_VALUEstrawberry.enum_valueThe definition of a enum value
INPUT_OBJECTstrawberry.inputThe definition of an input object type
INPUT_FIELD_DEFINITIONstrawberry.fieldThe definition of a field on an input type