Skip to main content
Version: 5.x.x

GraphQLContextFactory

note

If you are using graphql-kotlin-spring-server, see the Spring specific documentation.

GraphQLContextFactory is a generic method for generating a GraphQL context for each request.

interface GraphQLContextFactory<out Context : GraphQLContext, Request> {    suspend fun generateContext(request: Request): Context?    suspend fun generateContextMap(request: Request): Map<*, Any>?}

Given the generic server request, the interface should create a legacy GraphQLContext class and a new context map to be used for every new operation. The legacy context class must implement the GraphQLContext interface from graphql-kotlin-schema-generator. See execution context for more info on how the context can be used in the schema functions.

Nullable Context#

The factory may return null if a context is not required for execution. This allows the library to have a default factory that just returns null. If your custom factory never returns null, then there is no need to use nullable arguments. However, if your custom factory may return null, you must define the context argument as nullable in the schema functions or a runtime exception will be thrown.

@Deprecateddata class CustomContext(val value: String) : GraphQLContext
class CustomFactory : GraphQLContextFactory<CustomContext, ServerRequest> {    override suspend fun generateContext(request: ServerRequest): Context? {        if (isSpecialRequest(request)) {            return null        }
        val value = callSomeSuspendableService(request)        return CustomContext(value)    }
    override suspend fun generateContextMap(request: ServerRequest): Map<*, Any>? {        if (isSpecialRequest(request)) {            return null        }
        val value = callSomeSuspendableService(request)        return mapOf("myKey" to value)    }}
class MyQuery : Query {
    fun getResults(dfe: DataFetchingEnvironment, input: String): String {        val contextMapValue = dfe.graphQLContext.get("myKey")        val contextObjectValue = (dfe.context as? CustomContext)?.value        val contextValue = contextMapValue ?: contextObjectValue        if (contextValue != null) {            return getDataWithContextValue(input, contextValue)        }
        return getBasicData(input)    }}

Suspendable Factory#

The interface is marked as a suspend function to allow the asynchronous fetching of context data. This may be helpful if you need to call some other services to calculate a context value.

Server-Specific Abstractions#

A specific graphql-kotlin-*-server library may provide an abstract class on top of this interface so users only have to be concerned with the context class and not the server class type. For example the graphql-kotlin-spring-server provides the following class, which sets the request type:

abstract class SpringGraphQLContextFactory<out T : GraphQLContext> : GraphQLContextFactory<T, ServerRequest>

HTTP Headers and Cookies#

For common use cases around authorization, authentication, or tracing you may need to read HTTP headers and cookies. This should be done in the GraphQLContextFactory and relevant data should be added to the context to be accessible during schema exectuion.

Federated Tracing#

If you need federation tracing support, the context must implement the separate FederatedGraphQLContext interface from graphql-kotlin-federation.

The reference server implementation graphql-kotlin-spring-server supports federated tracing in the context.