Open onionhammer opened 10 months ago
Thanks for the suggestions @onionhammer !
I think it could be done by providing a custom fetch function? I see that approach suggested for graphql-request
library https://github.com/jasonkuhrt/graphql-request/issues/269#issuecomment-1703936594
Thanks for the suggestions @onionhammer !
I think it could be done by providing a custom fetch function? I see that approach suggested for
graphql-request
library https://github.com/jasonkuhrt/graphql-request/issues/269#issuecomment-1703936594
Unless I'm mistaken, it can be done with a custom fetch, but then one might as well not even use this library at all because you would have to reimplement pretty much everything
Check out the PR please, it would greatly improve the flexibility while also still allowing a user to utilize the parts of this library that are great
My suggestion is to run client.request()
by passing the id
string to it instead of query. Then deserialize the body
in custom fetch function and serialize it again with id
field. Something like this
async function customFetch(url, init) {
const { query, ...rest } = JSON.parse(init.body)
return fetch(url, { ...init, body: JSON.stringify({ ...rest, id: query }) })
}
@lynxtaa This works if the body is JSON and not FormData, which is not guaranteed. What is your objection to making the serialization itself more flexible? Perhaps you have suggestions on how I can change the PR to be less objectionable?
This works if the body is JSON and not FormData, which is not guaranteed
It's also possible to get an operations
field if body is not a string but FormData.
What is your objection to making the serialization itself more flexible?
I'm really grateful for your desire to improve the dev experience of this library and happy that you're using it :) I will think on implementing something like hooks to make it more flexible. So that the list of supported options and complexity would not grow and it'll be easier to support and maintain.
I would suggest using a custom fetch function for now. I know this solution is far from great, sorry for that. I'll keep this issue opened
Thank you for the suggestion, if it is not too inefficient, I will take your recommendation. Otherwise, I may just end up forking this library.
Here is what this workaround/hack looks like to anyone curious:
fetch: (url, init) => {
// eslint-disable-next-line prefer-const
let { body, ...rest } = init;
if (body instanceof FormData) {
const operationsString = body.get("operations");
if (!operationsString)
throw new Error("Missing operations");
const operations = JSON.parse(operationsString as string);
const id = operations.query;
body.set("operations", JSON.stringify({ ...operations, query: undefined, id }));
}
else {
const parsed = JSON.parse(body);
if (parsed.query) {
parsed.id = parsed.query;
delete parsed.query;
}
body = JSON.stringify(parsed);
}
return fetch(url, { ...rest, body });
},
Is your feature request related to a problem? Please describe. It would be great if this library support persisted queries, which means the server already knows the query the client is sending, and the client merely passes an "id" in the query string (GET) or "id" in the body (POST) rather than a
query
in the bodyDescribe the solution you'd like A way for
graphClient.request
to pass anid
corresponding to a query, or an alternativegraphClient.requestId()
where the first arg is an ID rather than the query itselfDescribe alternatives you've considered Alternatively, the library could provide a way to customize how operations are serialized, instead of just a hard-coded
JSON.stringify(...)