diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1f7ae75 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/vendor +coverage.txt diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..7deda91 --- /dev/null +++ b/go.mod @@ -0,0 +1,8 @@ +module github.com/shurcooL/graphql + +go 1.13 + +require ( + github.com/graph-gophers/graphql-go v0.0.0-20191115155744-f33e81362277 + github.com/stretchr/testify v1.4.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..4c89b17 --- /dev/null +++ b/go.sum @@ -0,0 +1,15 @@ +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/graph-gophers/graphql-go v0.0.0-20191115155744-f33e81362277 h1:E0whKxgp2ojts0FDgUA8dl62bmH0LxKanMoBr6MDTDM= +github.com/graph-gophers/graphql-go v0.0.0-20191115155744-f33e81362277/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= +github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/graphql.go b/graphql.go index 8520956..df2d9e5 100644 --- a/graphql.go +++ b/graphql.go @@ -9,25 +9,67 @@ import ( "net/http" "github.com/shurcooL/graphql/internal/jsonutil" - "golang.org/x/net/context/ctxhttp" ) +func getDefaultClientHeaders() map[string]string { + return map[string]string{ + "Content-Type": "application/json", + } +} + +// ClientOptFunc graphql client option +type ClientOptFunc func(*Client) + +// WithHeader set graphql client header +func WithHeader(key, val string) ClientOptFunc { + return func(c *Client) { + c.headers[key] = val + } +} + +// WithCookie set graphql client cookie +func WithCookie(key, val string) ClientOptFunc { + return func(c *Client) { + if c.cookies == nil { + c.cookies = map[string]string{} + } + c.cookies[key] = val + } +} + // Client is a GraphQL client. type Client struct { url string // GraphQL server URL. httpClient *http.Client + + headers, + cookies map[string]string } // NewClient creates a GraphQL client targeting the specified GraphQL server URL. // If httpClient is nil, then http.DefaultClient is used. func NewClient(url string, httpClient *http.Client) *Client { + var c *Client if httpClient == nil { httpClient = http.DefaultClient } - return &Client{ + c = &Client{ + headers: getDefaultClientHeaders(), url: url, httpClient: httpClient, } + + return c +} + +// NewClientWithOptions creates a GraphQL client, same as NewClient but with some options can used to set HTTP Header +func NewClientWithOptions(url string, httpClient *http.Client, opts ...ClientOptFunc) (c *Client) { + c = NewClient(url, httpClient) + for _, optf := range opts { + optf(c) + } + + return c } // Query executes a single GraphQL query request, @@ -65,8 +107,21 @@ func (c *Client) do(ctx context.Context, op operationType, v interface{}, variab if err != nil { return err } - resp, err := ctxhttp.Post(ctx, c.httpClient, c.url, "application/json", &buf) - if err != nil { + var ( + req *http.Request + resp *http.Response + ) + // fmt.Println(buf.String()) + if req, err = http.NewRequest("POST", c.url, &buf); err != nil { + return err + } + for k, v := range c.headers { + req.Header.Set(k, v) + } + for k, v := range c.cookies { + req.AddCookie(&http.Cookie{Name: k, Value: v}) + } + if resp, err = c.httpClient.Do(req.WithContext(ctx)); err != nil { return err } defer resp.Body.Close()