-
Notifications
You must be signed in to change notification settings - Fork 92
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
Conversation
Hi @pontusntengnas, Thanks for contributing. Your idea makes sense. However, we shouldn't duplicate the logic twice. You can create private functions for func constructQuery(v interface{}, variables map[string]interface{}, options ...Option) (string, *constructOptionsOutput, error) {
//
}
// 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) {
// ...
}
// 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 query, err
} Then pass the output to 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, optionOutput, err = constructQuery(v, variables, options...)
case mutationOperation:
query, optionOutput, err = constructMutation(v, variables, options...)
}
if err != nil {
return nil, nil, nil, Errors{newError(ErrGraphQLEncode, err)}
}
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 *constructOptionsOutput) ([]byte, *http.Response, io.Reader, Errors) {
in := GraphQLRequestPayload{
Query: query,
Variables: variables,
}
if options != nil {
in.OperationName = options.operationName
}
// ...
} For // 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 {
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) {
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
}
return data, nil
} |
Thank you for your feedback, it sounds great. I will come back with a more proper implementation according to your proposal. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
This PR sets the operation name not only in the query string but also in the request payload.
My usecase is that the server (gqlgen) only recognises the operation name if it exists in the payload and on the server I need the name for logging purposes.