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

Is there a way to access the raw http response? #293

Closed
adrianocr opened this issue Aug 2, 2023 · 2 comments
Closed

Is there a way to access the raw http response? #293

adrianocr opened this issue Aug 2, 2023 · 2 comments
Labels
enhancement New feature or request

Comments

@adrianocr
Copy link

Is your feature request related to a problem? Please describe.
I am using genqlient to query the shopify graphql api. It works fine but the shopify api is rate limited to 50 data points per second. To facilitate not being throttled the shopify api includes rate limit information (leaky bucket algorithm) as part of the response. A response looks like this:

{
	"data": {
		"products": {
			"nodes": []
		}
	},
	"extensions": {
		"cost": {
			"requestedQueryCost": 4,
			"actualQueryCost": 3,
			"throttleStatus": {
				"maximumAvailable": 1000.0,
				"currentlyAvailable": 997,
				"restoreRate": 50.0
			}
		}
	}
}

The extensions object provides the rate limit data. But genqlient only makes the products part of the response available.

Describe the solution you'd like
Ideally it would be nice to access extra data as part of the type genqlient returns for each query, but if that's not possible then accessing the raw http response would allow for a user to manually marshal the data into a type and access it.

@adrianocr adrianocr added the enhancement New feature or request label Aug 2, 2023
@benjaminjkraft
Copy link
Collaborator

benjaminjkraft commented Aug 3, 2023

Two options here that exist today:

First, customize the graphql.Client -- basically, write your own implementation of the interface (likely extending the provided one similar to how auth works) that extracts those extensions. (Actually, we already parse them to a map[string]interface{}.) That works well if you want to, say, retry at a given time, or attach data to the error, or update the context somehow (say, if you want to keep track in some quasi-global way of the last rate limit status). But it doesn't really let you add a field to the response for the caller to handle.

Alternately, the option use_extensions adds a return parameter with the extensions. This was added in #184 (see the issue #183 for a bit of discussion on why it's set up this way). It will work better if you want the caller to handle the extensions.

While writing this I realize we could maybe do better on the second half by letting you make the extensions typed? Something like

# genqlient.yaml
extensions_type: path/to/mypkg.Extensions
package mypkg
type Extensions struct {
  Cost struct { ... } `json:"cost"
}

and then instead of map[string]interface{} you get *mypkg.Extensions. Arguably we could even do that if you don't have use_extensions, just for the benefit of a custom graphql.Client. Not sure how important that is for your use case, but it seems reasonable to add.

@adrianocr
Copy link
Author

use_extensions is perfect, thank you so much. I had no idea it was an option. Resolved my issues

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants