graph-gophers / graphql-go

GraphQL server with a focus on ease of use
BSD 2-Clause "Simplified" License
4.64k stars 492 forks source link

Make it possible to access the "parent" `http.Request` or at least `http.Request.Headers` #505

Closed dhermes closed 2 years ago

dhermes commented 2 years ago

Why: I am using Hasura as a primary access to a database and graphql-go as a secondary set of queries and mutations (via the Hasura remote API feature). I'd like to be able to use the authorization header to verify a caller's JWT and extract information about them.

How: You could for example use context.WithValue() to "stash" these values on a context you pass through.

Alternatives: Use an HTTP middleware that "stashes" values somewhere stateful and then let the graphl-go compatible resolver pull from that stash.

pavelnikolov commented 2 years ago

I am not convinced that this is needed. The library can process GraphQL requests but the fact that you host it on an HTTP server is just an implementation detail. The resolvers should never be aware of this implementation detail. Indeed you could pass anything through the context and verify if the user is verified or not. Please, use the context of the query to pass anything you want with context.WithValue()

dhermes commented 2 years ago

We disagree, but thanks for the prompt response, it's great to have active maintainers!

For those who tread here in the future, this will have to suffice

type stashKey struct{}

schema, err := graphql.ParseSchema(schemaString, resolver, opts...)
// ... err handling
baseHandler := &relay.Handler{Schema: schema}

handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    ctx := r.Context()
    wrapped := context.WithValue(ctx, stashKey{}, "put stuff here")
    r2 := r.WithContext(wrapped)
    baseHandler.ServeHTTP(w, r2)
})