Skip to content

Commit f11335a

Browse files
committed
Add ContextHandler API function to externally provde net/context.Context.
Following graphql-go/graphql#98, it's now possible to provide a Context to the graphql resolve functions. This exposes that capability in the handler API. This follows the convention of putting the Context as the first arg, and the apparently evolving context-aware http handler func signature.
1 parent 4b27062 commit f11335a

File tree

2 files changed

+54
-3
lines changed

2 files changed

+54
-3
lines changed

handler.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"github.com/gorilla/schema"
1010
"github.com/graphql-go/graphql"
1111
"github.com/unrolled/render"
12+
"golang.org/x/net/context"
1213
)
1314

1415
const (
@@ -104,9 +105,9 @@ func getRequestOptions(r *http.Request) *requestOptions {
104105
}
105106
}
106107

107-
// ServeHTTP provides an entry point into executing graphQL queries
108-
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
109-
108+
// ContextHandler provides an entrypoint into executing graphQL queries with a
109+
// user-provided context.
110+
func (h *Handler) ContextHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) {
110111
// get query
111112
opts := getRequestOptions(r)
112113

@@ -116,13 +117,19 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
116117
RequestString: opts.Query,
117118
VariableValues: opts.Variables,
118119
OperationName: opts.OperationName,
120+
Context: ctx,
119121
}
120122
result := graphql.Do(params)
121123

122124
// render result
123125
h.render.JSON(w, http.StatusOK, result)
124126
}
125127

128+
// ServeHTTP provides an entrypoint into executing graphQL queries.
129+
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
130+
h.ContextHandler(context.Background(), w, r)
131+
}
132+
126133
type Config struct {
127134
Schema *graphql.Schema
128135
Pretty bool

handler_test.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"github.com/graphql-go/graphql/testutil"
1515
"github.com/graphql-go/handler"
1616
"github.com/graphql-go/relay/examples/starwars" // TODO: remove this dependency
17+
"golang.org/x/net/context"
1718
)
1819

1920
func decodeResponse(t *testing.T, recorder *httptest.ResponseRecorder) *graphql.Result {
@@ -39,6 +40,49 @@ func executeTest(t *testing.T, h *handler.Handler, req *http.Request) (*graphql.
3940
return result, resp
4041
}
4142

43+
func TestContextPropagated(t *testing.T) {
44+
myNameQuery := graphql.NewObject(graphql.ObjectConfig{
45+
Name: "Query",
46+
Fields: graphql.Fields{
47+
"name": &graphql.Field{
48+
Name: "name",
49+
Type: graphql.String,
50+
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
51+
return p.Context.Value("name"), nil
52+
},
53+
},
54+
},
55+
})
56+
myNameSchema, err := graphql.NewSchema(graphql.SchemaConfig{myNameQuery, nil})
57+
if err != nil {
58+
t.Fatal(err)
59+
}
60+
61+
expected := &graphql.Result{
62+
Data: map[string]interface{}{
63+
"name": "context-data",
64+
},
65+
}
66+
queryString := `query={name}`
67+
req, _ := http.NewRequest("GET", fmt.Sprintf("/graphql?%v", queryString), nil)
68+
69+
h := handler.New(&handler.Config{
70+
Schema: &myNameSchema,
71+
Pretty: true,
72+
})
73+
74+
ctx := context.WithValue(context.Background(), "name", "context-data")
75+
resp := httptest.NewRecorder()
76+
h.ContextHandler(ctx, resp, req)
77+
result := decodeResponse(t, resp)
78+
if resp.Code != http.StatusOK {
79+
t.Fatalf("unexpected server response %v", resp.Code)
80+
}
81+
if !reflect.DeepEqual(result, expected) {
82+
t.Fatalf("wrong result, graphql result diff: %v", testutil.Diff(expected, result))
83+
}
84+
}
85+
4286
func TestHandler_BasicQuery(t *testing.T) {
4387

4488
expected := &graphql.Result{

0 commit comments

Comments
 (0)