diff --git a/.travis.yml b/.travis.yml index 968922a..307c7d7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,7 @@ go: - 1.9.x - 1.10.x - 1.11.x + - 1.12.x before_install: - go get golang.org/x/lint/golint diff --git a/graphql.go b/graphql.go index 05c29b7..2c37292 100644 --- a/graphql.go +++ b/graphql.go @@ -61,7 +61,6 @@ type Client struct { func NewClient(endpoint string, opts ...ClientOption) *Client { c := &Client{ endpoint: endpoint, - Log: func(string) {}, } for _, optionFunc := range opts { optionFunc(c) @@ -73,7 +72,9 @@ func NewClient(endpoint string, opts ...ClientOption) *Client { } func (c *Client) logf(format string, args ...interface{}) { - c.Log(fmt.Sprintf(format, args...)) + if c.Log != nil { + c.Log(fmt.Sprintf(format, args...)) + } } // Run executes the query and unmarshals the response from the data field @@ -110,9 +111,7 @@ func (c *Client) runWithJSON(ctx context.Context, req *Request, resp interface{} } c.logf(">> variables: %v", req.vars) c.logf(">> query: %s", req.q) - gr := &graphResponse{ - Data: resp, - } + r, err := http.NewRequest(http.MethodPost, c.endpoint, &requestBody) if err != nil { return err @@ -126,28 +125,7 @@ func (c *Client) runWithJSON(ctx context.Context, req *Request, resp interface{} } } c.logf(">> headers: %v", r.Header) - r = r.WithContext(ctx) - res, err := c.httpClient.Do(r) - if err != nil { - return err - } - defer res.Body.Close() - var buf bytes.Buffer - if _, err := io.Copy(&buf, res.Body); err != nil { - return errors.Wrap(err, "reading body") - } - c.logf("<< %s", buf.String()) - if err := json.NewDecoder(&buf).Decode(&gr); err != nil { - if res.StatusCode != http.StatusOK { - return fmt.Errorf("graphql: server returned a non-200 status code: %v", res.StatusCode) - } - return errors.Wrap(err, "decoding response") - } - if len(gr.Errors) > 0 { - // return first error - return gr.Errors[0] - } - return nil + return c.doHTTP(ctx, r, resp) } func (c *Client) runWithPostFields(ctx context.Context, req *Request, resp interface{}) error { @@ -181,9 +159,7 @@ func (c *Client) runWithPostFields(ctx context.Context, req *Request, resp inter c.logf(">> variables: %s", variablesBuf.String()) c.logf(">> files: %d", len(req.files)) c.logf(">> query: %s", req.q) - gr := &graphResponse{ - Data: resp, - } + r, err := http.NewRequest(http.MethodPost, c.endpoint, &requestBody) if err != nil { return err @@ -197,17 +173,26 @@ func (c *Client) runWithPostFields(ctx context.Context, req *Request, resp inter } } c.logf(">> headers: %v", r.Header) + return c.doHTTP(ctx, r, resp) +} + +func (c *Client) doHTTP(ctx context.Context, r *http.Request, resp interface{}) error { r = r.WithContext(ctx) res, err := c.httpClient.Do(r) if err != nil { return err } defer res.Body.Close() + var buf bytes.Buffer if _, err := io.Copy(&buf, res.Body); err != nil { return errors.Wrap(err, "reading body") } c.logf("<< %s", buf.String()) + + gr := graphResponse{ + Data: resp, + } if err := json.NewDecoder(&buf).Decode(&gr); err != nil { if res.StatusCode != http.StatusOK { return fmt.Errorf("graphql: server returned a non-200 status code: %v", res.StatusCode) @@ -250,7 +235,7 @@ func ImmediatelyCloseReqBody() ClientOption { type ClientOption func(*Client) type graphErr struct { - Message string + Message string `json:"message"` } func (e graphErr) Error() string { @@ -258,8 +243,8 @@ func (e graphErr) Error() string { } type graphResponse struct { - Data interface{} - Errors []graphErr + Data interface{} `json:"data"` + Errors []graphErr `json:"errors"` } // Request is a GraphQL request.