Using Context
The GraphQL context object can be used to give every resolver in the schema access to some shared state for the current request. One common use case is to store the current User on the context object.
One important thing to note about Pothos is that every request is assumed to have a new unique context object, so be sure to set up your context objects in a way that they are unique to each request.
First let's define a User class that holds information about a user, and create a SchemaBuilder with a Context type that has a currentUser property.
Next, we will want to add something in our schema that uses the current user:
Finally, we need to actually create our context when a request is created.
Initialize context cache
Several Pothos plugins use the context object to cache data for the current request. Some examples include dataloaders and auth scopes. This caching mechanism works based on the assumption that the same context object is passed to every resolver in a request, and each request has a unique context object. This works for most applications without any additional configuration.
In some rare edge cases, you may have some additional logic added to your application that clones or mutates the context object throughout the execution of a request. To ensure that all plugins work correctly even if the context object is cloned, wrapped, or modified in a way that does not preserve its identity, you can manually initialize the context cache and attach it to the context object:
Context when using multiple protocols
In some specific situations multiple protocols could be used for handling the graphql operations against the same executable graphql schema. One common example of this is using HTTP(Hypertext Transfer Protocol) protocol for handling graphql query and mutation operations and using Websocket protocol for handling graphql subscription operations. Because the protocols are different, the protocol specific information that might be passed in the graphql context could differ depending on the graphql operation that is being executed. Now, our personal recommendation is to keep your executable graphql schema and its inner layers protocol agnostic to not have to deal with a situation like this.
We're working with two different graphql contexts within our graphql resolvers and we want strong type-safety while working with them. For this use case we recommend using typescript discriminated unions for combining types for different graphql contexts into a single union type that can be passed to pothos schema builder initializer. In the following example Context
is a union type between graphql context types for HTTP and Websocket protocol specific graphql contexts, where the isSubscription
boolean field is the discriminator. This context type is passed as the type for Context
field in the generic accepted by the pothos schema builder initializer. Within the resolver implementations for a graphql schema created using this pothos schema builder, the graphql context can be discriminated between its two protocol specific types by using the isSubscription
field. This would help us get the type-safe graphql context that we can make use of in our graphql resolvers. In the following code we perform this discrimination by checking the value of isSubscription
boolean field in the if
and else
blocks within the graphql resolvers: