Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set operation name on request payload #103

Merged
merged 3 commits into from
Aug 3, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
}

// ConstructQuery build GraphQL mutation string from struct and variables
hgiasac marked this conversation as resolved.
Show resolved Hide resolved
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
Loading