Allow customization of GraphQL fetch
The GraphQL fetch should allow for more custumization:
-
Currently the fetch call is fixed to query
elastic50, feels weird to have to use elastic50 as my query name even if I'm using 7.2 -
enforces the usage of a
hostparameter(which I dont use as the graphql proxy takes care of the host + credentials, therefore resulting in an error for me) -
Uses content type
application/graphqlwhile lots of implementations like Apollo seem to preferapplication/json -
ReactiveBase could take a transformRequest parameter, which seems to be ignored in case
graphQLUrlis used.
Simply changing application/graphql to application/json did not work for me and I had issues to get the right encoding.
This is how it worked for me:
const fetchGraphQL = (graphQLUrl, url, credentials, app, query) => {
const mSearchBody = JSON.stringify(query.map(item => JSON.stringify(item)));
const body = JSON.stringify({
query: `{ elastic72 { msearch ( index: "${app}", body: ${mSearchBody} ) } }`
});
return fetch(graphQLUrl, {
method: 'POST',
body,
headers: {
'Content-Type': 'application/json',
},
})
.then(res => res.json())
.then(jsonRes => jsonRes.data.elastic72.msearch)
.catch((error) => {
console.error(error);
});
};
export default fetchGraphQL;
I would need to make use of the host url and credentials parameter and see if they were provided, if yes build a url that should be provided as host parameter to the query in order to include all functionality. Would be interesting to see if the GraphQL proxy you are using would also accept the query in this encoding, if yes I could prepare a PR.
I had the same issue. Forking was not an ideal solution since there are multiple packages involved and keeping in sync would have been painful. I use apollo-server as a backend.
So here is what I did: I used xspy module which allows to modify requests before they are sent, and did this :
import xspy from 'xspy';
xspy.onRequest(request => {
// Intercept the good request.
if (
request.ajaxType === 'xhr' &&
request.method === 'POST' &&
request.headers['content-type'] !== 'application/json' &&
request.body.includes('elastic50')
) {
request.headers.accept = '*/*';
request.headers['content-type'] = 'application/json';
// Here you could inject authorization headers.
request.headers.authorization = `Bearer ${window.localStorage.getItem(
'token'
)}`;
request.body = JSON.stringify({
// My field is named "elastic" so we rename it here, and strip host argument.
query: request.body.replace(/elastic50\(.*\)/, 'elastic50:elastic')
});
}
});