Overview
For now, we'll keep things simple and try a classic "Hello world" example for our schema. Don't worry, we'll jump into playlists and tracks later on!
In this lesson, we will:
- Learn about the
Querytype - Create a schema based on the
Querytype
The Query type
The Query type defines a list of everything we're allowed to ask for from our GraphQL server. It's the entry point into our schema!
Everything GraphQL API-related will live inside the api folder. We'll keep root types such as Query and later on Mutation in the root of the api folder. All other object types will live in the api/types folder.
Let's create a file called query.py at the root of api.
At the top, let's import the strawberry module.
import strawberry
Then, we'll add a class called Query.
class Query:...
Right now, this is just a normal Python class. To define it as a GraphQL type, we apply the strawberry.type function.
strawberry.type
This function tells Strawberry that the class is a GraphQL type and should be included in the schema. It also finds all the properties of a class and adds them as fields of the GraphQL type.
But it does more than that! Strawberry uses dataclasses under the hood to create a fully functional class with constructors, equality checks, and more.
strawberry.type takes in multiple arguments, but two commonly-used arguments are:
description: sets the GraphQL type description to help API consumers make sense of what the type is or how it should be used.name: sets the name of the type in the GraphQL schema. By default, Strawberry will generate the name by converting the name of the class toPascalCase(a GraphQL common convention).
Let's go ahead and define the Query type as a GraphQL type. Just before the class definition, we'll apply the strawberry.type function and use it as a decorator. (That means we have to add the @ prefix!)
@strawberry.typeclass Query:
Inside the Query class, let's define the hello property, which returns a str type. (You can remove the ...!)
hello: str
This is the bare minimum we need for a valid GraphQL schema. The GraphQL schema equivalent in SDL would look something like this:
type Query {hello: String!}
Defining a resolver
We still need a way to return data for this field, using a resolver. To define a resolver, we use the strawberry.field function.
strawberry.field
This function tells Strawberry that a particular property of a class is a GraphQL field and can be resolved with a specific function.
strawberry.field takes in multiple arguments but three commonly-used arguments are:
resolver: the function name of the resolver responsible for returning data for the field.description: sets the GraphQL type description to help API consumers make sense of what the type is or how it should be used.name: sets the name of the type in the GraphQL schema. By default, Strawberry will generate the name by converting the name of the property tocamelCase.
Defining the hello resolver
Let's see this in action.
First, we'll define a new function, outside of the Query class, called get_hello. It returns a hard-coded string "Hello world".
def get_hello():return "Hello world"
Next, we'll need to point to this function as the resolver for the hello property. Inside the Query class, find the hello property and set it to the value of the strawberry.field function, passing in the resolver argument and setting it to get_hello.
hello: str = strawberry.field(resolver=get_hello)
Perfect, we've got the contents of the schema and the resolvers in place.
Creating a schema
Our GraphQL server needs to know about the Query type. In the previous lesson, we used ... as a placeholder for our schema. Let's update that to point to a real schema that includes the Query type.
First, we'll create a new file called schema.py in the api folder.
📦 odyssey-intro-strawberry┣ 📂 api┃ ┣ 📄 __init__.py┃ ┣ 📄 query.py┃ ┗ 📄 schema.py┣ 📂 data┃ ┗ 📄 openapi.json┣ 📄 main.py┣ 📄 pyproject.toml┣ 📄 README.md┣ 📄 requirements-dev.txt┗ 📄 requirements.txt
Inside, we'll import strawberry and the Query class we just created.
import strawberryfrom .query import Query
To create a schema, we use the strawberry.Schema class. This class takes in a query argument (the entry point into our schema). We'll point it to the Query type. We'll store this in a variable called schema.
schema = strawberry.Schema(query=Query)
We'll be adding more types to the schema throughout the course.
Updating the GraphQL endpoint
Now we can update our FastAPI app to use this schema! Jump back to the main.py file.
Let's import the schema object at the top of the file.
from api.schema import schema
Then, replace the ... placeholder with schema.
- graphql_router = GraphQLRouter(..., path="/", graphql_ide="apollo-sandbox")+ graphql_router = GraphQLRouter(schema, path="/", graphql_ide="apollo-sandbox")
Our GraphQL server should be ready to go!
Practice
Query type in GraphQL?Key takeaways
- The fields of the
Querytype are entry points into our schema. These are the top-level fields that a GraphQL consumer can query for. - We use the
strawberry.typeto define a class as a GraphQL type and should be included in the schema. It also finds all the properties of a class and adds them as fields of the GraphQL type. - We use the
strawberry.fieldfunction to define a particular property of a class as a GraphQL field and can be resolved with a specific function. - We can create a schema using the
strawberry.Schemaclass and pass theQuerytype to it.
Up next
Our GraphQL server is ready to receive queries. In the next lesson, we'll discover the best way to write and send queries: Apollo Explorer.
Share your questions and comments about this lesson
This course is currently in
You'll need a GitHub account to post below. Don't have one? Post in our Odyssey forum instead.