From b4c5a074b8250cb6470efbe18e5f2b028437fa37 Mon Sep 17 00:00:00 2001 From: Alex Sonneveld Date: Wed, 6 Feb 2019 10:28:07 +1100 Subject: [PATCH] Fix set header to JSON earlier in GraphQL response Update the GraphQL handler to set the Response Header to JSON earlier for error messages to be returned as JSON and not text/html. Fixes https://github.com/99designs/gqlgen/issues/519 == Notes: - Add checks for JSON Content-Type checks in decode bad queries tests --- handler/graphql.go | 2 +- handler/graphql_test.go | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/handler/graphql.go b/handler/graphql.go index e5e1bccd9c4..585897a9248 100644 --- a/handler/graphql.go +++ b/handler/graphql.go @@ -311,6 +311,7 @@ func (gh *graphqlHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } + w.Header().Set("Content-Type", "application/json") var reqParams params switch r.Method { case http.MethodGet: @@ -332,7 +333,6 @@ func (gh *graphqlHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusMethodNotAllowed) return } - w.Header().Set("Content-Type", "application/json") ctx := r.Context() diff --git a/handler/graphql_test.go b/handler/graphql_test.go index 377b773f901..4ea8cb58088 100644 --- a/handler/graphql_test.go +++ b/handler/graphql_test.go @@ -45,30 +45,35 @@ func TestHandlerPOST(t *testing.T) { t.Run("decode failure", func(t *testing.T) { resp := doRequest(h, "POST", "/graphql", "notjson") assert.Equal(t, http.StatusBadRequest, resp.Code) + assert.Equal(t, resp.HeaderMap.Get("Content-Type"), "application/json") assert.Equal(t, `{"errors":[{"message":"json body could not be decoded: invalid character 'o' in literal null (expecting 'u')"}],"data":null}`, resp.Body.String()) }) t.Run("parse failure", func(t *testing.T) { resp := doRequest(h, "POST", "/graphql", `{"query": "!"}`) assert.Equal(t, http.StatusUnprocessableEntity, resp.Code) + assert.Equal(t, resp.HeaderMap.Get("Content-Type"), "application/json") assert.Equal(t, `{"errors":[{"message":"Unexpected !","locations":[{"line":1,"column":1}]}],"data":null}`, resp.Body.String()) }) t.Run("validation failure", func(t *testing.T) { resp := doRequest(h, "POST", "/graphql", `{"query": "{ me { title }}"}`) assert.Equal(t, http.StatusUnprocessableEntity, resp.Code) + assert.Equal(t, resp.HeaderMap.Get("Content-Type"), "application/json") assert.Equal(t, `{"errors":[{"message":"Cannot query field \"title\" on type \"User\".","locations":[{"line":1,"column":8}]}],"data":null}`, resp.Body.String()) }) t.Run("invalid variable", func(t *testing.T) { resp := doRequest(h, "POST", "/graphql", `{"query": "query($id:Int!){user(id:$id){name}}","variables":{"id":false}}`) assert.Equal(t, http.StatusUnprocessableEntity, resp.Code) + assert.Equal(t, resp.HeaderMap.Get("Content-Type"), "application/json") assert.Equal(t, `{"errors":[{"message":"cannot use bool as Int","path":["variable","id"]}],"data":null}`, resp.Body.String()) }) t.Run("execution failure", func(t *testing.T) { resp := doRequest(h, "POST", "/graphql", `{"query": "mutation { me { name } }"}`) assert.Equal(t, http.StatusOK, resp.Code) + assert.Equal(t, resp.HeaderMap.Get("Content-Type"), "application/json") assert.Equal(t, `{"errors":[{"message":"mutations are not supported"}],"data":null}`, resp.Body.String()) }) }