6. Building a schema


Time to level up from "Hello world" to "Hello playlists"!

In this lesson, we will:

  • Examine a mockup design and create a from it
  • Create our first
  • Learn how to a with the description

The mockup

To kick things off, let's take a look at this page from the MusicMatcher app:

A grid of featured playlists

It showcases a grid of featured popular playlists that you may be interested in!

Breaking each playlist down, we can start to see what pieces of data the client app will need. This process of breaking down a mockup to pieces of data is called schema-first design.

The same mockup but with labels for each piece of data

A playlist needs a name and a description, which are both pieces of text.

Strawberry uses a code-first approach to implementing a but it's still helpful to keep the schema-first design principles in mind; thinking about what types and our functions will be defining based on the mockup designs and data that the app developers expect.

The Playlist type

Let's start with the Playlist type. In the types folder, create a file called playlist.py.

📦 odyssey-intro-strawberry
┣ 📂 api
┃ ┣ 📂 types
┃ ┃ ┣ 📄 __init__.py
┃ ┃ ┗ 📄 playlist.py
┃ ┣ 📄 __init__.py
┃ ┣ 📄 query.py
┃ ┗ 📄 schema.py
┣ 📄 // other folders & files

We'll import strawberry at the top, define the class and apply the @strawberry.type annotation to it.

import strawberry
class Playlist:
# Playlist properties go here

Inside the Playlist class, we'll start by defining the name of our playlist as a property with type str.

name: str

By default, this is non-nullable, so a playlist requires a name.

Next, let's define the playlist's description, which is also a str type. A description can be null, so we'll mark it as such using the | None syntax.

description: str | None

One more thing! Even though it wasn't part of the mockup, it's common practice to also define an identifier for a class. Looking ahead, when we click into a playlist, we'll need to have a way to retrieve the details for that specific playlist, and that's exactly what the identifier (or ID) is for.

IDs in are represented as ID types. Python doesn't have a built-in ID type, but fortunately, Strawberry provides a strawberry.ID type that we can use.

id: strawberry.ID

The three properties we've defined for a playlist (id, name and description) act as the resolvers for those . Behind the scenes, Strawberry automatically generates for each field based on the property name. For example, the name will have a that returns the value of the name property.

Exploring the schema

What does this Playlist class look like in our now? Let's find out!

We'll first need to register the Playlist class with our .

Open up the api/schema.py file and import the Playlist class at the top of the file.

from .types.playlist import Playlist

Next, where we defined strawberry.Schema, we'll add another parameter called types and assign the Playlist class in the list it accepts.

schema = strawberry.Schema(query=Query, types=[Playlist])

Save all our changes and restart the server.

Back to Sandbox, let's check out the Schema page. Select Objects on the left-hand side and click Playlist.


Sandbox showing Schema Reference and Objects selected

Awesome, we've accounted for all the playlist !


Sandbox showing Playlist schema

Right now, the details column shows "No description". Although the names feel fairly self-explanatory right now, it's good practice to the types and fields of your schema, especially for consumers of our .

Documenting our schema

We use descriptions to a schema. (Not to be confused with our playlist's description field!) In Strawberry we use the description of strawberry.type, which takes a string as an that describes the type.

Back to our Playlist class, let's add the description to the @strawberry.type decorator.

description="A curated collection of tracks designed for a specific activity or mood."
class Playlist:

Next, let's add descriptions to the Playlist . We'll need to use the strawberry.field function for each , passing in the description .

id: strawberry.ID = strawberry.field(description="The ID for the playlist.")
name: str = strawberry.field(description="The name of the playlist.")
description: str | None = strawberry.field(
description="Describes the playlist, what to expect and entices the user to listen."

Save our changes and switch over to Sandbox to see our clear and helpful descriptions!


Sandbox showing Playlist schema with descriptions


Which of the following statements are true about schema documentation?
In Apollo Sandbox, what page would you navigate to for a detailed reference to your GraphQL schema?

Key takeaways

  • Breaking down a mockup into data pieces and implementing features based on client application needs is known as schema-first design.
  • The description on both strawberry.field and strawberry.type is used to add clear and helpful descriptions to types and . It will be displayed in GraphQL IDEs such as .
  • The strawberry.ID type defines the identifier for the type. It indicates that the associated property represents a unique identifier.

Up next

We need a way to for a playlist. Right now, it's just floating in our schema without a way to access it. Let's make it available through our Query type — our entry point to the schema!


Share your questions and comments about this lesson

This course is currently in

. Your feedback helps us improve! If you're stuck or confused, let us know and we'll help you out. All comments are public and must follow the Apollo Code of Conduct. Note that comments that have been resolved or addressed may be removed.

You'll need a GitHub account to post below. Don't have one? Post in our Odyssey forum instead.