Я пытаюсь объединить несколько запросов 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.
Вы не можете сделать это с помощью простых текстовых манипуляций; вам нужно проанализировать запросы GraphQL и соединить их вместе. Это может усложниться при наличии динамического сопоставления типов и фрагментов.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Мой ответ становится слишком длинным для комментария, поэтому я решил написать прямой ответ здесь. Во-первых, я думаю, что оба комментария действительно полезны. Существует решение, которое позволяет двум запросам совместно использовать HTTP-запрос, который уже может быть оптимизацией, которую вы ищете. Кроме того, слияние запросов не является тривиальным. Это требует больших усилий, чтобы сделать это вплоть до полевого уровня. Не только фрагменты могут сделать это сложным, вы также должны учитывать переменные. Насколько я знаю, общедоступного решения для этого нет, поэтому вам придется сделать это самостоятельно. Также я не слышал о компании, которая делает это. Я думаю, что тот факт, что решения нет, является показателем того, что, возможно, не стоит этого делать.
Я могу только догадываться о вашей проблеме, но еще один способ уменьшить количество запросов, отправляемых внешним приложением, — использовать фрагменты. Хотя ваши фрагменты не могут иметь переменных, здоровая структура компонентов все равно будет очень хорошо сочетаться с фрагментами:
fragment PostHeader on Post {
title
description
}
fragment PostMeta on Post {
tags
author {
name
}
}
query {
post(id: 1234) {
...PostHeader
...PostMeta
}
}
Это выглядит как очень полезное решение во многих случаях. Я ожидаю много совпадений между входными запросами, что сделает это решение менее идеальным, поэтому я постараюсь создать свою собственную функцию слияния.
Мы написали код для объединения фрагментов, с автоматическим присвоением имен фрагментам и удалением повторяющихся фрагментов, и выложили его здесь: github.com/SVT/graphql-дефрагментатор
Благодаря параметризованным фрагментам вы можете учитывать переменные! Предполагая, что 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, в чем была ошибка, кроме имени пакета?
@DomasLapinskas Ограничивает ли это сетевые вызовы только одним?
вы пытаетесь минимизировать количество HTTP-запросов? если да, это может помочь blog.apollographql.com/query-batching-in-apollo-63acfd859862