Apollo-link: [Функция] Метод GET apollo-link-http удаляет игнорируемые символы

Созданный на 10 июн. 2019  ·  3Комментарии  ·  Источник: apollographql/apollo-link

В проекте, над которым я работаю, мы используем метод GET, чтобы получить преимущества HTTP-кеширования. Это работает успешно, но мы заметили, что параметр запроса содержит символы, которые не нужны для выполнения запроса.

Пример
Ниже приведен пример, в котором мы используем graphql-tag для синтаксического анализа запроса. Новые строки включены для удобства чтения запроса.

import gql from 'graphql-tag';

const HERO_QUERY = gql`
  query HERO_QUERY {
    hero {
      name
      friends {
        name
      }
    }
  }
`;

Фактическое поведение приводит к следующему HTTP-запросу:

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

Ожидаемое поведение - запрос GET без лишних символов:

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

В настоящее время я напрямую не вижу способа / возможности реализовать обходной путь для достижения того же результата. Если этот запрос имеет смысл, я могу предоставить PR для внесения необходимых изменений.

https://github.com/apollographql/apollo-link/blob/951217bad34c91f89c1f167cc809bd0cc18fd922/packages/apollo-link-http/src/httpLink.ts#L198 -L203

Тело rewriteURIForGET можно удалить перед прохождением encodeURIComponent .

Можно было бы повторно использовать логику, которая используется в пакете graphql , где доступен служебный метод stripIgnoredCharacters .

На пакет graphql уже есть ссылка в apollo-link-http и его можно использовать повторно, либо можно напрямую включить настраиваемую логику для очистки запроса.

Самый полезный комментарий

В итоге мы исправили apollo-link-http-common через https://www.npmjs.com/package/patch-package, чтобы использовать stripIgnoredCharacters сразу после использования принтера:

патчи / 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,

Все 3 Комментарий

Я попытался внести изменения вне библиотеки apollo-link-http , создав пользовательское расширение ApolloLink чтобы удалить запрос до того, как он будет передан в createHttpLink но, к сожалению, безуспешно.

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' }),
]);

Кажется, что print из graphql/language/printer снова добавляет ненужные символы.

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
  }
}

Этот же метод print похоже, также используется apollo-link-http-common который используется в apollo-link-http для создания запроса GET.

https://github.com/apollographql/apollo-link/blob/c32e170b72ae1a94cea1c633f977d2dbfcada0e1/packages/apollo-link-http-common/src/index.ts#L239

Также попробовал вышеуказанное с чем-то вроде:

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),
    });
  });
};

Но получите массу предупреждений о повторном использовании имен фрагментов и проблемах с записью в хранилище.

Я бы использовал HTTP-перехватчик, но тогда у вас есть проблемы с разными хешами при использовании APQ. У меня есть запросы размером 44 КБ, полные %20%20%20 . Подумайте, если бы я мог удалить игнорируемые символы, он, вероятно, был бы вдвое меньше.

Вы не можете даже предварительно обработать его, потому что ApolloClient просто добавляет __typename повсюду и повторно преобразует его:

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
    }
  }
`;

В итоге мы исправили apollo-link-http-common через https://www.npmjs.com/package/patch-package, чтобы использовать stripIgnoredCharacters сразу после использования принтера:

патчи / 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,
Была ли эта страница полезной?
0 / 5 - 0 рейтинги