-
Notifications
You must be signed in to change notification settings - Fork 836
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add context throughout graphql #25
Conversation
I like the concept you're going after. But I don't agree with using a context. I think it would better if the request were attached to the Essentially what I"m getting at is that I think the use case of this change is far too small to suit a general purpose library, where as providing the |
The only issue I can see with that is if there were several resolve functions that needed to be run to return a request, wouldn't each of them need to independently lookup the session data from the database (sure there could be a caching layer to make it that efficient but that is just one use-case). Having a context would allow you to store and share any state between all functions needed to resolve an http request. Context also has the other benefits such as being able to manage a request deadline and kill slow resolve functions which you couldn't do by just passing the http_request round. The context could be put on |
+1. Love to have this. Needed for GAE apps where all the operations are request bounded. |
Hi guys, @tallstreet Thanks for the PR! Really appreciate you putting your time to contribute to this project. I agree that having a per-request context would be really useful, so the question now is how do we allow user to store context for them to use. Currently, type GQLFRParams struct {
Source interface{}
Args map[string]interface{}
Info GraphQLResolveInfo
Schema GraphQLSchema
}
type GraphQLFieldResolveFn func(p GQLFRParams) interface{}
type GraphQLResolveInfo struct {
FieldName string
FieldASTs []*ast.Field
ReturnType GraphQLOutputType
ParentType GraphQLCompositeType
Schema GraphQLSchema
Fragments map[string]ast.Definition
RootValue interface{}
Operation ast.Definition
VariableValues map[string]interface{}
} So right now we have the following possibilities:
May I proposed that we look into using
This was brought up by an issue in graphql/graphql-js#56 and it seems that it was designed for this particular use-case. The issue for package gql
type GraphqlParams struct {
...
RootObject map[string]interface{}
}
package executor
type ExecuteParams struct {
...
Root interface{}
}
package types
type GraphQLResolveInfo struct {
...
RootValue interface{}
} One benefit is that it does not force user to use a particular context library. What you guys think? /cc @chris-ramon |
It indeed work now, but involves unnecessary casting. at the handler
and in the field config
like @sogko suggested, the API should be consistent and should retain the name and the type At the same time, like the issue graphql/graphql-js#56 , we almost always need a request context, and like it to be explicit and convenient. So, I back this PR or a field ctx (context.Context) as part of RootValue . For the reference, see a different implementation here also by @tallstreet which uses context throughout. https://github.com/tallstreet/graphql |
My original comments were uneducated. After I remarked here I went looking for how graphql-js handled sessions (for authentication purposes) and from there attempted to use the RootValue piece as demonstrated for graphql-js but with little success (mostly probably my own fault but I haven't had a significant amount of time to look at it again recently). So I'm totally on board with @sogko's suggestion of doing it through the RootValue and I think I agree with @bsr203, if I understand his post correctly. Keeping that as a general purpose map[string]interface{} opens it up to any implementation chosen by consumers - not just Context, or Request, etc... |
I was just going to post an issue on the inconsistent API passing root value, Maybe the RootObject should be an interface because anyway we are going to attach structs to it like session data or some other context which we will be typecasting to anyway. |
Any update on this one? |
I think it would be great to see this. context.Conext is quickly becoming the standard for controlling goroutine cancellation and passing data down a chain of handlers. It's easy to use and implement :) I built GitHub.com/pressly/chi which shows you those benefits as an http service. You can picture how the http endpoint to graphql would pass it's context to graphql for timing out, passing some state by composition, graceful shutdowns, or invoking a cancellation of a running goroutine. Please :)
|
I think having this and |
@bsr203 I saw that issue too. I agree an error should be returned instead of panic`ing. |
Well, I totally missed this PR and went off and did the same thing. Now that I'm all caught up, my 2 cents:
(minor side note: humorously, of the three possible locations to insert a Context (func signature, Params, or Info), I happened to pick the the third one that nobody else did. d'oh) |
closing this one in favor of #98 - thanks a lot for great feedback 👍 |
It would be useful to have a context that was maintained through the graphql library so when resolving fields we can change what we want to return based on the context of the request.
See https://blog.golang.org/context for use cases.