Skip to content

Commit

Permalink
feat(client): expose Full method to provide custom responses (#11)
Browse files Browse the repository at this point in the history
  • Loading branch information
steebchen committed Oct 28, 2019
1 parent 3fb4256 commit af7c05d
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 15 deletions.
44 changes: 30 additions & 14 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ type Response struct {
// request is the payload for GraphQL queries
type gqlRequest struct {
Query string `json:"query"`
Variables map[string]interface{} `json:"variables,omitempty"`
OperationName string `json:"operationName,omitempty"`
Variables map[string]interface{} `json:"variables"`
OperationName *string `json:"operationName"`
}

// Send a GraphQL request to struct or map
Expand Down Expand Up @@ -58,30 +58,47 @@ func (c *Client) Send(ctx context.Context, dest interface{}, query string, varia
// Raw sends a basic GraphQL request without any struct types.
// Parameter `variables` can be either a map or a struct
func (c *Client) Raw(ctx context.Context, query string, variables map[string]interface{}) (*Response, error) {
var err error
payload := gqlRequest{
Query: query,
Variables: variables,
}

response := &Response{}
err := c.do(ctx, payload, variables, response)
if err != nil {
return nil, errors.Wrap(err, "raw decode")
}

payload := &gqlRequest{
return response, err
}

func (c *Client) Full(ctx context.Context, query string, variables map[string]interface{}, response interface{}) error {
payload := gqlRequest{
Query: query,
Variables: variables,
}

return c.do(ctx, payload, variables, response)
}

func (c *Client) do(ctx context.Context, payload gqlRequest, variables map[string]interface{}, response interface{}) error {
requestBody, err := json.Marshal(payload)
if err != nil {
return nil, errors.Wrap(err, "raw encode")
return errors.Wrap(err, "raw encode")
}

req, err := http.NewRequest("post", c.url, bytes.NewBuffer(requestBody))
req, err := http.NewRequest("POST", c.url, bytes.NewBuffer(requestBody))

if err != nil {
return nil, err
return err
}

req.Header.Set("content-type", "application/json")
req = req.WithContext(ctx)

rawResponse, err := c.http.Do(req)
if err != nil {
return nil, errors.Wrap(err, "raw post")
return errors.Wrap(err, "raw post")
}
defer func() {
_ = rawResponse.Body.Close()
Expand All @@ -90,20 +107,19 @@ func (c *Client) Raw(ctx context.Context, query string, variables map[string]int
responseBody, err := ioutil.ReadAll(rawResponse.Body)

if err != nil {
return nil, errors.Wrap(err, "raw read")
return errors.Wrap(err, "raw read")
}

if rawResponse.StatusCode != http.StatusOK {
return nil, errors.Errorf("http status code %d with response %s", rawResponse.StatusCode, responseBody)
return errors.Errorf("http status code %d with response %s", rawResponse.StatusCode, responseBody)
}

// decode it into map string first, let mapstructure do the final decode
// mapstructure is way stricter about unknown fields, can handle embedded structs and more
respDataRaw := &Response{}
err = json.Unmarshal(responseBody, &respDataRaw)
err = json.Unmarshal(responseBody, &response)
if err != nil {
return nil, errors.Wrap(err, "raw decode")
return errors.Wrap(err, "raw decode")
}

return respDataRaw, nil
return nil
}
2 changes: 1 addition & 1 deletion client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func mockServer(t *testing.T) *httptest.Server {
panic(err)
}

expect := `{"query":"query GetUser { user(id: $id) { id name } }","variables":{"id":"1"}}`
expect := `{"query":"query GetUser { user(id: $id) { id name } }","variables":{"id":"1"},"operationName":null}`
require.Equal(t, expect, string(b))

err = json.NewEncoder(w).Encode(map[string]interface{}{
Expand Down

0 comments on commit af7c05d

Please sign in to comment.