De acordo com os documentos , a opção fetchOptions
nos permite definir o método da solicitação como GET
. Eu esperava que, depois de fazer isso, a consulta fosse incluída como um parâmetro de string de consulta em vez do corpo da solicitação; O Chrome gera um erro se você tentar fazer uma solicitação GET com um corpo.
Resultado pretendido:
Uma string de consulta deve ser construída se o método de solicitação for GET.
Resultado real:
O corpo da solicitação é usado.
Como reproduzir o problema:
client.query({
context: {
fetchOptions: {
method: 'GET',
},
},
query: QUERY,
variables: { query },
})
@szdc sim, isso definitivamente não funciona! Você estaria aberto para adicioná-lo? Algo como https://github.com/apollographql/apollo-link/issues/257 pode ser uma boa solução também para transformar a solicitação antes de ser enviada?
cc @arackaf @ outlaw11a @puttyman que todos têm interesse nisso! Deve ser uma pequena mudança para adicionar!
Vou adicioná-lo se ninguém mais quiser.
@szdc @arackaf então descobrimos que isso já é possível! Vou fazer um teste e documentos em breve mostrando como isso pode ser feito sem mudanças internas
@szdc @ Outlaw11A @arackaf aqui está como fazer:
const customFetch = (uri, options) => {
const { body, ...newOptions } = options;
const queryString = objectToQuery(JSON.parse(body));
requestedString = uri + queryString;
return fetch(requestedString, newOptions);
};
const link = createHttpLink({
uri: "data",
fetchOptions: { method: "GET" },
fetch: customFetch
});
@jbaxleyiii que parece incrível! Apenas curioso de onde objectToQuery está vindo? Existe um utilitário no npm para isso? Eu imagino que seria muito fácil apenas rolar o seu próprio, se necessário - basicamente mapear Object.keys para
escapeUriComponnt(`${k}=${obj[k]}`).join("&");
ou algo semelhante
https://www.apollographql.com/docs/link/links/http.html#Sending -GET-requests-custom-fetching
@arackaf veja o comentário:
// turn the object into a query string, try object-to-querystring package
@jbaxleyiii funciona! É incrível!
Eu só tenho um problema.
A string de consulta criada:
http://localhost/graphql?operationName=AllPlayersQuery&variables=%5Bobject%20Object%5D&query=query%20All...
contém este: variables=%5Bobject%20Object%5D
que é um problema.
Como consertar isto?
Isso se parece com a serialização de URI padrão - não pense que você pode evitá-la - por que é um problema?
URI padrão? Este: %5Bobject%20Object%5D
?
encodeURIComponent ('books (title: "Hello World") {Book {title}}')
books(title%3A%22Hello%20World%22)%7BBook%7Btitle%7D%7D
Minha consulta no Apollo é:
query AllPlayers {
players {
id
name
surname
}
e então eu tenho o problema com [Object object]
variáveis vazias com o código postado por @jbaxleyiii.
Aqui está um aplicativo de reação barebones (criado usando create-react-app) que busca via GET e funciona - consulte index.js
: https://github.com/usefulio/example-graphql-via-get-react-app
@johnunclesam obviamente variables
não é serializado antes da codificação. Eu simplesmente ajustei meu método de busca personalizado (obtido do repositório de exemplo) adicionando um JSON.stringify
condicional:
const customFetch = (uri, options) => {
const {body, ...newOptions} = options;
const parsedBody = JSON.parse(body);
const command = omitBy(parsedBody, isEmpty);
if (command.variables) {
command.variables = JSON.stringify(command.variables);
}
const requestedString = uri + '?' + queryString.stringify(command);
return fetch(requestedString, newOptions);
};
Então, para que useGETForQueries
usado? Por que a busca personalizada não está embutida quando useGETForQueries=true
?
Como diferencio consulta e mutação? Eu só quero usar GET para consulta (para cache DNS).
Este é um problema antigo anterior a useGETForQueries, que foi adicionado um pouco depois de ser corrigido por https://github.com/apollographql/apollo-link/pull/510
umm, useGETForQueries parece não estar funcionando.
Especificamente nesta linha, parece haver um bug:
let {
uri = '/graphql',
// use default global fetch if nothing passed in
fetch: fetcher,
includeExtensions,
useGETForQueries,
...requestOptions
} = linkOptions;
deve ser algo como:
let {
uri = '/graphql',
// use default global fetch if nothing passed in
fetch: fetcher,
includeExtensions,
fetchOptions,
...requestOptions
} = linkOptions;
let {
useGETForQueries
} = fetchOptions;
O que te faz dizer isso? Como você está chamando createHttpLink
?
Minha observação acima foi de percorrer o código com um depurador, mas eu teria que fazer isso novamente para reproduzir.
O código que decidimos é este:
import omitBy from 'lodash.omitby';
import isEmpty from 'lodash.isempty';
const graphQLUrl = 'http://the.server.com/graphql';
const customFetch = (uri, options) => {
const { body, credentials, headers, ...newOptions } = options;
let fetchUri = uri;
if (body) {
const parsedBody = JSON.parse(body);
const command = omitBy(parsedBody, isEmpty);
fetchUri = uri + "?" + queryString.stringify(command);
}
return fetch(fetchUri, newOptions);
};
const link = createHttpLink({
uri: graphQLUrl,
fetchOptions: { method: "GET" },
fetch: customFetch
});
Acho que minha pergunta é, se você estivesse passando useGETForQueries
dentro de fetchOptions
vez de diretamente dentro de createHttpLink
, então esse seria o comportamento que você observaria, mas também não seria como a API funciona. Eu sugiro tentar novamente!
Comentários muito úteis
@szdc @ Outlaw11A @arackaf aqui está como fazer: