Skip to content

Commit

Permalink
set the operation name to the request payload if exist (shurcooL#103)
Browse files Browse the repository at this point in the history
* set the operation name to the request payload if exist

---------

Co-authored-by: Toan Nguyen <[email protected]>
  • Loading branch information
pontusntengnas and hgiasac authored Aug 3, 2023
1 parent 9585e63 commit 1956215
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 20 deletions.
28 changes: 22 additions & 6 deletions graphql.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,26 +104,32 @@ func (c *Client) NamedMutateRaw(ctx context.Context, name string, m interface{},
func (c *Client) buildAndRequest(ctx context.Context, op operationType, v interface{}, variables map[string]interface{}, options ...Option) ([]byte, *http.Response, io.Reader, Errors) {
var query string
var err error
var optionOutput *constructOptionsOutput
switch op {
case queryOperation:
query, err = ConstructQuery(v, variables, options...)
query, optionOutput, err = constructQuery(v, variables, options...)
case mutationOperation:
query, err = ConstructMutation(v, variables, options...)
query, optionOutput, err = constructMutation(v, variables, options...)
}

if err != nil {
return nil, nil, nil, Errors{newError(ErrGraphQLEncode, err)}
}

return c.request(ctx, query, variables, options...)
return c.request(ctx, query, variables, optionOutput)
}

// Request the common method that send graphql request
func (c *Client) request(ctx context.Context, query string, variables map[string]interface{}, options ...Option) ([]byte, *http.Response, io.Reader, Errors) {
func (c *Client) request(ctx context.Context, query string, variables map[string]interface{}, options *constructOptionsOutput) ([]byte, *http.Response, io.Reader, Errors) {
in := GraphQLRequestPayload{
Query: query,
Variables: variables,
}

if options != nil {
in.OperationName = options.operationName
}

var buf bytes.Buffer
err := json.NewEncoder(&buf).Encode(in)
if err != nil {
Expand Down Expand Up @@ -249,14 +255,24 @@ func (c *Client) do(ctx context.Context, op operationType, v interface{}, variab
// Executes a pre-built query and unmarshals the response into v. Unlike the Query method you have to specify in the query the
// fields that you want to receive as they are not inferred from v. This method is useful if you need to build the query dynamically.
func (c *Client) Exec(ctx context.Context, query string, v interface{}, variables map[string]interface{}, options ...Option) error {
data, resp, respBuf, errs := c.request(ctx, query, variables, options...)
optionsOutput, err := constructOptions(options)
if err != nil {
return err
}

data, resp, respBuf, errs := c.request(ctx, query, variables, optionsOutput)
return c.processResponse(v, data, resp, respBuf, errs)
}

// Executes a pre-built query and returns the raw json message. Unlike the Query method you have to specify in the query the
// fields that you want to receive as they are not inferred from the interface. This method is useful if you need to build the query dynamically.
func (c *Client) ExecRaw(ctx context.Context, query string, variables map[string]interface{}, options ...Option) ([]byte, error) {
data, _, _, errs := c.request(ctx, query, variables, options...)
optionsOutput, err := constructOptions(options)
if err != nil {
return nil, err
}

data, _, _, errs := c.request(ctx, query, variables, optionsOutput)
if len(errs) > 0 {
return data, errs
}
Expand Down
48 changes: 34 additions & 14 deletions query.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,48 +43,68 @@ func constructOptions(options []Option) (*constructOptionsOutput, error) {
return output, nil
}

// ConstructQuery build GraphQL query string from struct and variables
func ConstructQuery(v interface{}, variables map[string]interface{}, options ...Option) (string, error) {
func constructQuery(v interface{}, variables map[string]interface{}, options ...Option) (string, *constructOptionsOutput, error) {
query, err := query(v)
if err != nil {
return "", err
return "", nil, err
}

optionsOutput, err := constructOptions(options)
if err != nil {
return "", err
return "", nil, err
}

if len(variables) > 0 {
return fmt.Sprintf("query %s(%s)%s%s", optionsOutput.operationName, queryArguments(variables), optionsOutput.OperationDirectivesString(), query), nil
return fmt.Sprintf("query %s(%s)%s%s", optionsOutput.operationName, queryArguments(variables), optionsOutput.OperationDirectivesString(), query), optionsOutput, nil
}

if optionsOutput.operationName == "" && len(optionsOutput.operationDirectives) == 0 {
return query, nil
return query, optionsOutput, nil
}

return fmt.Sprintf("query %s%s%s", optionsOutput.operationName, optionsOutput.OperationDirectivesString(), query), nil
return fmt.Sprintf("query %s%s%s", optionsOutput.operationName, optionsOutput.OperationDirectivesString(), query), optionsOutput, nil
}

// ConstructQuery build GraphQL mutation string from struct and variables
func ConstructMutation(v interface{}, variables map[string]interface{}, options ...Option) (string, error) {
query, err := query(v)
// ConstructQuery build GraphQL query string from struct and variables
func ConstructQuery(v interface{}, variables map[string]interface{}, options ...Option) (string, error) {
query, _, err := constructQuery(v, variables, options...)
if err != nil {
return "", err
}

return query, err
}

func constructMutation(v interface{}, variables map[string]interface{}, options ...Option) (string, *constructOptionsOutput, error) {
query, err := query(v)
if err != nil {
return "", nil, err
}

optionsOutput, err := constructOptions(options)
if err != nil {
return "", err
return "", nil, err
}

if len(variables) > 0 {
return fmt.Sprintf("mutation %s(%s)%s%s", optionsOutput.operationName, queryArguments(variables), optionsOutput.OperationDirectivesString(), query), nil
return fmt.Sprintf("mutation %s(%s)%s%s", optionsOutput.operationName, queryArguments(variables), optionsOutput.OperationDirectivesString(), query), optionsOutput, nil
}

if optionsOutput.operationName == "" && len(optionsOutput.operationDirectives) == 0 {
return "mutation" + query, nil
return "mutation" + query, optionsOutput, nil
}

return fmt.Sprintf("mutation %s%s%s", optionsOutput.operationName, optionsOutput.OperationDirectivesString(), query), optionsOutput, nil
}

// ConstructMutation build GraphQL mutation string from struct and variables
func ConstructMutation(v interface{}, variables map[string]interface{}, options ...Option) (string, error) {
query, _, err := constructMutation(v, variables, options...)
if err != nil {
return "", err
}

return fmt.Sprintf("mutation %s%s%s", optionsOutput.operationName, optionsOutput.OperationDirectivesString(), query), nil
return query, err
}

// ConstructSubscription build GraphQL subscription string from struct and variables
Expand Down

0 comments on commit 1956215

Please sign in to comment.