-
Hello everyone, I currently have a header that the graphQL server I am using sends that contains a request Id. |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 16 replies
-
Generally the GraphQL spec would advise to put these into |
Beta Was this translation helpful? Give feedback.
-
I am still fairly new to graphQL unfortunately. You are saying the graphQL server should put this on that extensions field then. I will let the back-end developer know. Stilll how would I go about getting the fetch response if its a success ? Like coding myself a custom exchange using urql? |
Beta Was this translation helpful? Give feedback.
-
pasting here my final version of the code (js only) import {
make,
filter,
merge,
mergeMap,
pipe,
share,
takeUntil,
onPush,
} from 'wonka';
import {
makeFetchBody,
makeFetchURL,
makeFetchOptions,
} from '@urql/core/internal';
import { makeResult, makeErrorResult } from '@urql/core';
const executeFetch = (
operation,
url,
fetchOptions,
) => {
const fetcher = operation.context.fetch;
let statusNotOk = false;
let response;
let requestId;
return (fetcher || fetch)(url, fetchOptions)
.then((res) => {
statusNotOk = res.status < 200
|| res.status >= (fetchOptions.redirect === 'manual' ? 400 : 300);
response = res;
requestId = res.headers.get('X-Request-ID') || 'n/a';
return res.json();
})
.then((res) => {
if (!('data' in res) && !('errors' in res)) {
throw new Error('No Content');
}
return Object.assign(makeResult(operation, res, response), {
extensions: {
...result.extensions,
requestId,
},
});
})
.catch((error) => {
if (error.name !== 'AbortError') {
return Object.assign(makeErrorResult(
operation,
statusNotOk ? new Error(response.statusText) : error,
response), {
extensions: {
...result.extensions,
requestId,
},
});
}
});
};
const makeFetchSource = (
operation,
url,
fetchOptions,
) => make(({ next, complete }) => {
let ended = false;
Promise.resolve()
.then(() => {
if (!ended) {
return executeFetch(operation, url, fetchOptions);
}
})
.then((result) => {
if (!ended) {
ended = true;
if (result) {
next(result);
}
complete();
}
});
return () => {
ended = true;
};
});
export default function fetchExchange({ forward, dispatchDebug }) {
return (ops$) => {
const sharedOps$ = share(ops$);
const fetchResults$ = pipe(
sharedOps$,
filter(operation => operation.kind === 'query' || operation.kind === 'mutation'),
mergeMap((operation) => {
const { key } = operation;
const teardown$ = pipe(
sharedOps$,
filter(op => op.kind === 'teardown' && op.key === key),
);
const body = makeFetchBody(operation);
const url = makeFetchURL(operation, body);
const fetchOptions = makeFetchOptions(operation, body);
dispatchDebug({
type: 'fetchRequest',
message: 'A fetch request is being executed.',
operation,
data: {
url,
fetchOptions,
},
});
return pipe(
makeFetchSource(operation, url, fetchOptions),
takeUntil(teardown$),
onPush((result) => {
const error = !result.data ? result.error : undefined;
dispatchDebug({
type: error ? 'fetchError' : 'fetchSuccess',
message: `A ${
error ? 'failed' : 'successful'
} fetch response has been returned.`,
operation,
data: {
url,
fetchOptions,
value: error || result,
},
});
}),
);
}),
);
const forward$ = pipe(
sharedOps$,
filter(operation => operation.kind !== 'query' && operation.kind !== 'mutation'),
forward,
);
return merge([fetchResults$, forward$]);
};
} |
Beta Was this translation helpful? Give feedback.
pasting here my final version of the code (js only)