Graphql объединить (объединить) несколько запросов в один?

Я пытаюсь объединить несколько запросов Graphql в один запрос с помощью JavaScript.
Я ищу что-то вроде этого:

let query3 = mergeQueries(query1, query2);

Мы не будем знать заранее, какие запросы будут объединены.

Предположим, у меня есть такие запросы:

входной запрос1:

{
  post(id: 1234) {
    title
    description
  }
}

входной запрос2:

{
  post(id: 1234) {
    tags
    author {
      name
    }
  }
}

Тогда я хотел бы, чтобы результат query3 был:
результат запроса3:

{
  post(id: 1234) {
    title
    tags
    description
    author {
      name
    }
  }
}

Это будет та же функциональность, что и у lodash _.merge() для объектов JSON, но с запросами Graphql вместо объектов JSON.

вы пытаетесь минимизировать количество HTTP-запросов? если да, это может помочь blog.apollographql.com/query-batching-in-apollo-63acfd859862

Navid Yousefzai 18.02.2019 10:35

Вы не можете сделать это с помощью простых текстовых манипуляций; вам нужно проанализировать запросы GraphQL и соединить их вместе. Это может усложниться при наличии динамического сопоставления типов и фрагментов.

David Maze 18.02.2019 12:56
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
12
2
18 787
3

Ответы 3

Мой ответ становится слишком длинным для комментария, поэтому я решил написать прямой ответ здесь. Во-первых, я думаю, что оба комментария действительно полезны. Существует решение, которое позволяет двум запросам совместно использовать HTTP-запрос, который уже может быть оптимизацией, которую вы ищете. Кроме того, слияние запросов не является тривиальным. Это требует больших усилий, чтобы сделать это вплоть до полевого уровня. Не только фрагменты могут сделать это сложным, вы также должны учитывать переменные. Насколько я знаю, общедоступного решения для этого нет, поэтому вам придется сделать это самостоятельно. Также я не слышал о компании, которая делает это. Я думаю, что тот факт, что решения нет, является показателем того, что, возможно, не стоит этого делать.

Я могу только догадываться о вашей проблеме, но еще один способ уменьшить количество запросов, отправляемых внешним приложением, — использовать фрагменты. Хотя ваши фрагменты не могут иметь переменных, здоровая структура компонентов все равно будет очень хорошо сочетаться с фрагментами:

fragment PostHeader on Post {
  title
  description
}

fragment PostMeta on Post {
  tags
  author {
    name
  }
}

query {
  post(id: 1234) {
    ...PostHeader
    ...PostMeta
  }
}

Это выглядит как очень полезное решение во многих случаях. Я ожидаю много совпадений между входными запросами, что сделает это решение менее идеальным, поэтому я постараюсь создать свою собственную функцию слияния.

Hendrik Jan 19.02.2019 08:00

Мы написали код для объединения фрагментов, с автоматическим присвоением имен фрагментам и удалением повторяющихся фрагментов, и выложили его здесь: github.com/SVT/graphql-дефрагментатор

Anders Kindberg 23.08.2019 09:19

Благодаря параметризованным фрагментам вы можете учитывать переменные! Предполагая, что post является полем корневого типа запроса, комбинированный запрос, относящийся к приведенному выше примеру, будет выглядеть так:

fragment PostHeader on RootQueryType {
  post(id: $id) {
    tags
    author {
      name
    }
  }
}

fragment PostMeta on RootQueryType {
  post(id: $id) {
    tags
    author {
      name
    }
  }
}

# ID being the id type
query(id: ID! = 1234) {
  ...PostHeader
  ...PostMeta
}

или, скорее, в реальном сценарии вы будете передавать идентификатор динамически (например, в своем почтовом запросе), см.: https://graphql.org/learn/queries/#variables

Я написал для этого библиотеку: https://github.com/domasx2/graphql-combine-запрос

import comineQuery from 'graphql-combine-query'

import gql from 'graphql-tag'

const fooQuery = gql`
  query FooQuery($foo: String!) {
    getFoo(foo: $foo)
  }
`

const barQuery = gql`
  query BarQuery($bar: String!) {
    getBar(bar: $bar)
  }
`

const { document, variables } = combineQuery('FooBarQuery')
  .add(fooQuery, { foo: 'some value' })
  .add(barQuery, { bar: 'another value' })

console.info(variables)
// { foo: 'some value', bar: 'another value' }

print(document)
/*
query FooBarQuery($foo: String!, $bar: String!) {
   getFoo(foo: $foo)
   getBar(bar: $bar)
}
*/

Это казалось обнадеживающим, но это действительно свежо и содержит ошибки. Не последним из них является неправильное написание имени пакета в package.json.

ivanjonas 16.07.2020 15:28

@ivanjonas, в чем была ошибка, кроме имени пакета?

Domas Lapinskas 16.07.2020 19:31

@DomasLapinskas Ограничивает ли это сетевые вызовы только одним?

Shujath 11.02.2021 14:17

Другие вопросы по теме