Starlette: Providing custom context to GraphQLApp

Created on 1 Aug 2019  路  6Comments  路  Source: encode/starlette

Hi.

It would be useful to be able to inject values into the context provided to the graphql schema when using the GraphQLApp. It can be used to provide dependencies, for example.

Thanks!

Most helpful comment

The frustrating thing about this is that it's possible but forces layering violations: I can't write a Graphene schema that isn't intimately aware of the web server that's going to be executing it :(

All 6 comments

I'm not exactly sure what you mean here - can you provide an example?

The request is currently available, which means you have access to any per-request specific information you might need.

@tomchristie I guess the request can be used to provide per-request data and dependencies(e.g. injected into the session through middlewares).

I think it makes sense to expose the graphql context as well, especially to provide data or assets not tied to the request and its scope(e.g. things that can be defined once on startup, or statically). The purpose of the graphql context is to be used to provide information and assets for the resolvers(that's clearly stated in the documentation), so I don't think a web framework integration should get to keep it for itself.

Here's an example:

class Query(graphene.ObjectType):
    hello = graphene.String(name=graphene.String(default_value="stranger"))

    def resolve_hello(self, info, name):
        api = info.context["api_connection"]
        return api.hello()

app = Starlette()
graphql_app = GraphQLApp(schema=graphene.Schema(query=Query))

@app.on_event('startup')
def setup_graphql_context():
    graphql_app.add_context(api_connection=SomeApiClient(...))

app.add_route('/', graphql_app)

I know this is a few months old but I'd like to bump it as I ran up against the same limitation. I think the line in question is this one.
To give a real world example say I'd like to pass the sqlalchemy db session to my GraphQL resolver as context during an execute see this graphene example for what I'm talking about.
Access to execute's context is one example but there are other graphql functionalities that are implicitly disallowed at the moment due to restrictions on what can be passed to execute.

@Upgwades For a db session, you can set request.state.session in a http middleware. Then in the resolver you can access it as info.context["request"].state.session.

The frustrating thing about this is that it's possible but forces layering violations: I can't write a Graphene schema that isn't intimately aware of the web server that's going to be executing it :(

Yes, good point. @tomchristie could you consider reopening this?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jordic picture jordic  路  6Comments

kouohhashi picture kouohhashi  路  3Comments

tomchristie picture tomchristie  路  5Comments

Immortalin picture Immortalin  路  3Comments

PeriGK picture PeriGK  路  5Comments