Pour un projet sur lequel je travaille, nous utilisons la méthode GET pour tirer parti de la mise en cache HTTP. Cela fonctionne avec succès mais nous remarquons que le paramètre de requête contient des caractères qui ne sont pas nécessaires à l'exécution de la requête.
Exemple
Ci-dessous un exemple où nous utilisons graphql-tag
pour analyser la requête. Les sauts de ligne sont inclus pour la lisibilité de la requête.
import gql from 'graphql-tag';
const HERO_QUERY = gql`
query HERO_QUERY {
hero {
name
friends {
name
}
}
}
`;
Le comportement réel se traduit par la requête HTTP suivante :
GET /graphql?query=query%20HERO_QUERY%20%7B%0A%20%20hero%20%7B%0A%20%20%20%20name%0A%20%20%20%20friends%20%7B%0A%20%20%20%20%20%20name%0A%20%20%20%20%20%20__typename%0A%20%20%20%20%7D%0A%20%20%20%20__typename%0A%20%20%7D%0A%7D%0A&operationName=HERO_QUERY&variables=%7B%7D HTTP/1.1
Host: localhost:3000
Connection: keep-alive
content-type: application/json
Le comportement attendu est une requête GET sans caractères inutiles :
GET /graphql?query=query%20HERO_QUERY%7Bhero%7Bname%20friends%7Bname%7D%7D%7D&operationName=HERO_QUERY&variables=%7B%7D HTTP/1.1
Host: localhost:3000
Connection: keep-alive
content-type: application/json
Je ne vois actuellement pas directement un moyen/possibilité de mettre en œuvre une solution de contournement pour obtenir le même résultat. Si cette demande a du sens, je peux fournir un PR pour que cela fasse les modifications nécessaires.
Le corps de rewriteURIForGET
peut être dépouillé avant de passer par le encodeURIComponent
.
Il serait possible de réutiliser la logique utilisée dans le package graphql
où il existe une méthode utilitaire disponible stripIgnoredCharacters .
Le package graphql
est déjà référencé dans apollo-link-http
et peut être réutilisé ou une logique personnalisée peut être directement incluse pour nettoyer la requête.
J'ai essayé de faire la modification en dehors de la bibliothèque apollo-link-http
en créant une extension personnalisée ApolloLink
pour supprimer la requête avant qu'elle ne soit transmise à createHttpLink
mais sans succès malheureusement.
import { ApolloLink } from 'apollo-link';
import gql from 'graphql-tag';
import { print } from 'graphql/language/printer';
import { stripIgnoredCharacters } from 'graphql/utilities/stripIgnoredCharacters';
class CreateShortQueryLink extends ApolloLink {
request(operation, forward) {
const strippedQuery = stripIgnoredCharacters(print(operation.query));
const request = {
...operation,
getContext: operation.getContext,
setContext: operation.setContext,
query: gql(strippedQuery),
};
return forward(request);
}
}
const link = ApolloLink.from([
new CreateShortQueryLink(),
createHttpLink({ uri: 'http://localhost:3000/graphql' }),
]);
Il semble que le print
de graphql/language/printer
ajoute à nouveau les caractères inutiles.
print(gql('query Posts{posts(orderBy:id_DESC){id title __typename}}'))
// outputs
query Posts{posts(orderBy:id_DESC){id title __typename}} query Posts {
posts(orderBy: id_DESC) {
id
title
__typename
}
}
Cette même méthode print
semble également être utilisée par apollo-link-http-common
qui est utilisée dans apollo-link-http
pour créer la requête GET.
J'ai aussi essayé ce qui précède avec quelque chose comme :
export const createMinifyLink = () => {
return new ApolloLink((operation: Operation, forward: NextLink) => {
const stripped = stripIgnoredCharacters(operation.query.loc!.source);
return forward({
...operation,
getContext: operation.getContext,
setContext: operation.setContext,
query: gql(stripped),
});
});
};
Mais recevez un tas d'avertissements sur la réutilisation des noms de fragments et les problèmes d'écriture dans le stockage.
J'utiliserais un intercepteur HTTP, mais vous rencontrez alors des problèmes avec des hachages différents lors de l'utilisation d'APQ. J'ai des requêtes de %20%20%20
Ko et pleines de
Vous ne pouvez même pas le pré-traiter car ApolloClient ajoute simplement __typename partout et le ré-embellit :
export function stripIgnoredCharactersGql(literals: string[], ...placeholders: any[]) {
const strippedLiterals = literals.map(str => stripIgnoredCharacters(str));
return gql(strippedLiterals, ...placeholders);
}
export const configQuery = stripIgnoredCharactersGql`
query {
hello {
world
}
}
`;
Nous avons fini par corriger apollo-link-http-common via https://www.npmjs.com/package/patch-package pour utiliser stripIgnoredCharacters juste après l'utilisation de l'imprimante :
patchs/apollo-link-http-common+0.2.13.patch
diff --git a/node_modules/apollo-link-http-common/lib/index.js b/node_modules/apollo-link-http-common/lib/index.js
index 05cd095..c79da1b 100644
--- a/node_modules/apollo-link-http-common/lib/index.js
+++ b/node_modules/apollo-link-http-common/lib/index.js
@@ -2,6 +2,7 @@
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var printer_1 = require("graphql/language/printer");
+var utilities_1 = require("graphql/utilities/stripIgnoredCharacters");
var ts_invariant_1 = require("ts-invariant");
var defaultHttpOptions = {
includeQuery: true,
@@ -91,6 +92,7 @@ exports.selectHttpOptionsAndBody = function (operation, fallbackConfig) {
body.extensions = extensions;
if (http.includeQuery)
body.query = printer_1.print(query);
+ body.query = utilities_1.stripIgnoredCharacters(body.query);
return {
options: options,
body: body,
Commentaire le plus utile
Nous avons fini par corriger apollo-link-http-common via https://www.npmjs.com/package/patch-package pour utiliser stripIgnoredCharacters juste après l'utilisation de l'imprimante :
patchs/apollo-link-http-common+0.2.13.patch