Overview
We've got a client ready to fetch data from the Spotify API. We could use this client directly in our resolvers, but that would lead to quite a bit of code duplication. Instead, we'll use the context
feature of Strawberry to create the client once and share it across all resolvers.
In this lesson, we will:
- Learn about the
context
in Strawberry - Learn how to use the
info
argument to access thecontext
in our resolvers
What is the context
?
The context
in Strawberry is an object that allows us to pass any kind of data to our resolvers. Usually, it's used for things like database connections or authentication information.
We'll be using context
to share the Spotify client across all our resolvers.
Instantiating the client
To create an instance of the Spotify client, we'll make use of FastAPI's lifespan feature.
FastAPI's lifespan
FastAPI's lifespan feature enables us to run code when the application starts and stops. This is useful for setting up resources that need to be created once and shared across requests (just like our Spotify client!).
Open up the main.py
file, where all the server code lives.
We'll import a few things at the top: the asynccontextmanager
(which we'll need for the lifespan), the mock_spotify_rest_api_client.client
, and Request
from FastAPI.
from contextlib import asynccontextmanagerfrom mock_spotify_rest_api_client.client import Clientfrom fastapi import Request
Next, we can define the lifespan function, decorating it with @asynccontextmanager
.
@asynccontextmanagerasync def lifespan(app):...
Inside, we'll instantiate the Client
class, giving it the base_url
parameter with the Spotify API endpoint as the value. We'll also name this instance as spotify_client
.
@asynccontextmanagerasync def lifespan(app):async with Client(base_url="https://spotify-demo-api-fe224840a08c.herokuapp.com/v1") as spotify_client:...
To make spotify_client
available in the FastAPI app, we can yield
an object containing it. This object will be available on the request
object under request.state
later on.
yield {"spotify_client": spotify_client}
Note: Code before the yield
function runs before the application starts. You can read more about FastAPI's lifespan in the docs.
Finally, let's pass the lifespan
into the FastAPI
constructor down below.
app = FastAPI(lifespan=lifespan)
Great! The FastAPI app has access to the Spotify client, but we still need to pass it along to the resolvers using context
.
Creating the context
object
Let's start by defining an async function called context_getter
. It accepts an argument called request
of type Request
.
async def context_getter(request: Request):...
The request
object represents the GraphQL request, which includes the GraphQL operation and any HTTP headers. Additionally, it contains the spotify_client
object we set up in the lifespan
function earlier!
We can now access the spotify_client
object from the request.state
object.
spotify_client = request.state.spotify_client
Then, we'll return an object, representing the context
object. Inside, we'll include the spotify_client
.
return {"spotify_client": spotify_client}
Finally, down below, we'll pass this context_getter
function into the context_getter
parameter of the GraphQLRouter
class.
graphql_router = GraphQLRouter(schema, path="/", graphql_ide="apollo-sandbox", context_getter=context_getter)
Strawberry automatically calls the context_getter
on every request and passes the result to the resolvers via the info
argument, which we'll tackle in the next lesson.
Key takeaways
- The
context
in Strawberry allows us to pass data to our resolvers. We use thecontext_getter
parameter inGraphQLRouter
to return a customcontext
object. - FastAPI's lifespan allows us to create resources that need to be shared across requests.
Up next
It's time for the resolver function to start making real requests to the Spotify API.
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.