From 937540d2448b145a693a69716c7bfee763787383 Mon Sep 17 00:00:00 2001 From: Ben Kraft Date: Thu, 25 Mar 2021 13:58:41 -0700 Subject: [PATCH] make client an interface --- example/generated.go | 4 +- generate/operation.go.tmpl | 2 +- generate/testdata/InputObject.graphql.go | 2 +- .../testdata/InterfaceNoFragments.graphql.go | 2 +- generate/testdata/ListInput.graphql.go | 2 +- generate/testdata/QueryWithAlias.graphql.go | 2 +- .../testdata/QueryWithDoubleAlias.graphql.go | 2 +- generate/testdata/QueryWithEnums.graphql.go | 2 +- generate/testdata/QueryWithSlices.graphql.go | 2 +- generate/testdata/QueryWithStructs.graphql.go | 2 +- generate/testdata/SimpleInput.graphql.go | 2 +- generate/testdata/SimpleQuery.graphql.go | 2 +- generate/testdata/TypeName.graphql.go | 2 +- generate/testdata/UnionNoFragments.graphql.go | 2 +- generate/testdata/UsesEnumTwice.graphql.go | 2 +- generate/testdata/unexported.graphql.go | 2 +- graphql/client.go | 48 +++++++++++++++++-- 17 files changed, 61 insertions(+), 21 deletions(-) diff --git a/example/generated.go b/example/generated.go index 5bbee88..1533d13 100644 --- a/example/generated.go +++ b/example/generated.go @@ -26,7 +26,7 @@ type getViewerViewerUser struct { func getViewer( ctx context.Context, - client *graphql.Client, + client graphql.Client, ) (*getViewerResponse, error) { var retval getViewerResponse err := client.MakeRequest( @@ -47,7 +47,7 @@ query getViewer { // getUser gets the given user's name from their username. func getUser( ctx context.Context, - client *graphql.Client, + client graphql.Client, login string, ) (*getUserResponse, error) { variables := map[string]interface{}{ diff --git a/generate/operation.go.tmpl b/generate/operation.go.tmpl index 67f26fd..cfa5148 100644 --- a/generate/operation.go.tmpl +++ b/generate/operation.go.tmpl @@ -24,7 +24,7 @@ func {{.Name}}( ctx {{$.Config.ContextType}}, {{end}} {{- if not $.Config.ClientGetter -}} - client *graphql.Client, + client graphql.Client, {{end}} {{- range .Args -}} {{.GoName}} {{.GoType}}, diff --git a/generate/testdata/InputObject.graphql.go b/generate/testdata/InputObject.graphql.go index e307f3c..284fc90 100644 --- a/generate/testdata/InputObject.graphql.go +++ b/generate/testdata/InputObject.graphql.go @@ -30,7 +30,7 @@ const ( ) func InputObjectQuery( - client *graphql.Client, + client graphql.Client, query UserQueryInput, ) (*InputObjectQueryResponse, error) { variables := map[string]interface{}{ diff --git a/generate/testdata/InterfaceNoFragments.graphql.go b/generate/testdata/InterfaceNoFragments.graphql.go index 66391e7..422f348 100644 --- a/generate/testdata/InterfaceNoFragments.graphql.go +++ b/generate/testdata/InterfaceNoFragments.graphql.go @@ -94,7 +94,7 @@ func (v InterfaceNoFragmentsQueryRootTopicChildrenVideo) implementsGraphQLInterf } func InterfaceNoFragmentsQuery( - client *graphql.Client, + client graphql.Client, ) (*InterfaceNoFragmentsQueryResponse, error) { var retval InterfaceNoFragmentsQueryResponse err := client.MakeRequest( diff --git a/generate/testdata/ListInput.graphql.go b/generate/testdata/ListInput.graphql.go index 236d79f..ff01793 100644 --- a/generate/testdata/ListInput.graphql.go +++ b/generate/testdata/ListInput.graphql.go @@ -15,7 +15,7 @@ type ListInputQueryUser struct { } func ListInputQuery( - client *graphql.Client, + client graphql.Client, names []string, ) (*ListInputQueryResponse, error) { variables := map[string]interface{}{ diff --git a/generate/testdata/QueryWithAlias.graphql.go b/generate/testdata/QueryWithAlias.graphql.go index 9b05058..5fca827 100644 --- a/generate/testdata/QueryWithAlias.graphql.go +++ b/generate/testdata/QueryWithAlias.graphql.go @@ -15,7 +15,7 @@ type QueryWithAliasUser struct { } func QueryWithAlias( - client *graphql.Client, + client graphql.Client, ) (*QueryWithAliasResponse, error) { var retval QueryWithAliasResponse err := client.MakeRequest( diff --git a/generate/testdata/QueryWithDoubleAlias.graphql.go b/generate/testdata/QueryWithDoubleAlias.graphql.go index 1944fe3..1c1b9a7 100644 --- a/generate/testdata/QueryWithDoubleAlias.graphql.go +++ b/generate/testdata/QueryWithDoubleAlias.graphql.go @@ -16,7 +16,7 @@ type QueryWithDoubleAliasUser struct { } func QueryWithDoubleAlias( - client *graphql.Client, + client graphql.Client, ) (*QueryWithDoubleAliasResponse, error) { var retval QueryWithDoubleAliasResponse err := client.MakeRequest( diff --git a/generate/testdata/QueryWithEnums.graphql.go b/generate/testdata/QueryWithEnums.graphql.go index ed0d39a..7ef0f68 100644 --- a/generate/testdata/QueryWithEnums.graphql.go +++ b/generate/testdata/QueryWithEnums.graphql.go @@ -22,7 +22,7 @@ const ( ) func QueryWithEnums( - client *graphql.Client, + client graphql.Client, ) (*QueryWithEnumsResponse, error) { var retval QueryWithEnumsResponse err := client.MakeRequest( diff --git a/generate/testdata/QueryWithSlices.graphql.go b/generate/testdata/QueryWithSlices.graphql.go index d406d01..b9091bc 100644 --- a/generate/testdata/QueryWithSlices.graphql.go +++ b/generate/testdata/QueryWithSlices.graphql.go @@ -18,7 +18,7 @@ type QueryWithSlicesUser struct { } func QueryWithSlices( - client *graphql.Client, + client graphql.Client, ) (*QueryWithSlicesResponse, error) { var retval QueryWithSlicesResponse err := client.MakeRequest( diff --git a/generate/testdata/QueryWithStructs.graphql.go b/generate/testdata/QueryWithStructs.graphql.go index 887ee6b..9a9559a 100644 --- a/generate/testdata/QueryWithStructs.graphql.go +++ b/generate/testdata/QueryWithStructs.graphql.go @@ -20,7 +20,7 @@ type QueryWithStructsUserAuthMethodsAuthMethod struct { } func QueryWithStructs( - client *graphql.Client, + client graphql.Client, ) (*QueryWithStructsResponse, error) { var retval QueryWithStructsResponse err := client.MakeRequest( diff --git a/generate/testdata/SimpleInput.graphql.go b/generate/testdata/SimpleInput.graphql.go index b34d90e..2127493 100644 --- a/generate/testdata/SimpleInput.graphql.go +++ b/generate/testdata/SimpleInput.graphql.go @@ -15,7 +15,7 @@ type SimpleInputQueryUser struct { } func SimpleInputQuery( - client *graphql.Client, + client graphql.Client, name string, ) (*SimpleInputQueryResponse, error) { variables := map[string]interface{}{ diff --git a/generate/testdata/SimpleQuery.graphql.go b/generate/testdata/SimpleQuery.graphql.go index f1b8b0d..ab1e804 100644 --- a/generate/testdata/SimpleQuery.graphql.go +++ b/generate/testdata/SimpleQuery.graphql.go @@ -15,7 +15,7 @@ type SimpleQueryUser struct { } func SimpleQuery( - client *graphql.Client, + client graphql.Client, ) (*SimpleQueryResponse, error) { var retval SimpleQueryResponse err := client.MakeRequest( diff --git a/generate/testdata/TypeName.graphql.go b/generate/testdata/TypeName.graphql.go index fc6d890..d2bf790 100644 --- a/generate/testdata/TypeName.graphql.go +++ b/generate/testdata/TypeName.graphql.go @@ -16,7 +16,7 @@ type TypeNameQueryUser struct { } func TypeNameQuery( - client *graphql.Client, + client graphql.Client, ) (*TypeNameQueryResponse, error) { var retval TypeNameQueryResponse err := client.MakeRequest( diff --git a/generate/testdata/UnionNoFragments.graphql.go b/generate/testdata/UnionNoFragments.graphql.go index 6492c6c..fe64fb3 100644 --- a/generate/testdata/UnionNoFragments.graphql.go +++ b/generate/testdata/UnionNoFragments.graphql.go @@ -72,7 +72,7 @@ func (v *UnionNoFragmentsQueryResponse) UnmarshalJSON(b []byte) error { } func UnionNoFragmentsQuery( - client *graphql.Client, + client graphql.Client, ) (*UnionNoFragmentsQueryResponse, error) { var retval UnionNoFragmentsQueryResponse err := client.MakeRequest( diff --git a/generate/testdata/UsesEnumTwice.graphql.go b/generate/testdata/UsesEnumTwice.graphql.go index 2bf8784..84e099b 100644 --- a/generate/testdata/UsesEnumTwice.graphql.go +++ b/generate/testdata/UsesEnumTwice.graphql.go @@ -34,7 +34,7 @@ type UsesEnumTwiceQueryResponse struct { } func UsesEnumTwiceQuery( - client *graphql.Client, + client graphql.Client, ) (*UsesEnumTwiceQueryResponse, error) { var retval UsesEnumTwiceQueryResponse err := client.MakeRequest( diff --git a/generate/testdata/unexported.graphql.go b/generate/testdata/unexported.graphql.go index 215e0cc..a9fb34e 100644 --- a/generate/testdata/unexported.graphql.go +++ b/generate/testdata/unexported.graphql.go @@ -30,7 +30,7 @@ const ( ) func unexported( - client *graphql.Client, + client graphql.Client, query userQueryInput, ) (*unexportedResponse, error) { variables := map[string]interface{}{ diff --git a/graphql/client.go b/graphql/client.go index ad707bc..e3310bd 100644 --- a/graphql/client.go +++ b/graphql/client.go @@ -10,17 +10,57 @@ import ( "github.com/vektah/gqlparser/gqlerror" ) -type Client struct { +// Client is the interface that the generate code calls into to actually make +// requests. +type Client interface { + // MakeRequest must make a request to the client's GraphQL API. + // + // ctx is the context that should be used to make this request. If context + // is disabled in the genql settings, this will be set to + // context.Background(). + // + // query is the literal string representing the GraphQL query, e.g. + // `query myQuery { myField }`. variables contains the GraphQL variables + // to be sent along with the query, or may be nil if there are none. + // Typically, GraphQL APIs will accept a JSON payload of the form + // {"query": "query myQuery { ... }", "variables": {...}}` + // but MakeRequest may use some other transport, handle extensions, or set + // other parameters, if it wishes. + // + // retval is a pointer to the struct representing the query result, e.g. + // new(myQueryResponse). Typically, GraphQL APIs will return a JSON + // payload of the form + // {"data": {...}, "errors": {...}} + // and retval is designed so that `data` will json-unmarshal into `retval`. + // (Errors are returned.) But again, MakeRequest may customize this. + MakeRequest( + ctx context.Context, + query string, + retval interface{}, + variables map[string]interface{}, + ) error +} + +type client struct { endpoint string method string httpClient *http.Client } -func NewClient(endpoint string, httpClient *http.Client) *Client { +// NewClient returns a Client which makes requests to the given endpoint, +// suitable for most users. +// +// The client makes requests to the given GraphQL endpoint using standard +// GraphQL HTTP-over-JSON transport. It will use the given http client, or +// http.DefaultClient if a nil client is passed. +// +// The typical method of adding authentication headers is to wrap the client's +// Transport to add those headers. See example/caller.go for an example. +func NewClient(endpoint string, httpClient *http.Client) Client { if httpClient == nil { httpClient = http.DefaultClient } - return &Client{endpoint, http.MethodPost, httpClient} + return &client{endpoint, http.MethodPost, httpClient} } type payload struct { @@ -33,7 +73,7 @@ type response struct { Errors gqlerror.List `json:"errors"` } -func (client *Client) MakeRequest(ctx context.Context, query string, retval interface{}, variables map[string]interface{}) error { +func (client *client) MakeRequest(ctx context.Context, query string, retval interface{}, variables map[string]interface{}) error { body, err := json.Marshal(payload{ Query: query, Variables: variables,