Мне удается найти решение для моего варианта использования, поэтому я оставлю его здесь на случай, если кто-нибудь столкнется с этим потоком ...
Как уже упоминалось, для создания единой конечной точки следует использовать вышивание из нескольких сегментов API (микросервисы). В случае, если вы попытаетесь сшить схемы, содержащие одинаковые типы или запросы, ваш запрос будет «перенаправлен» на предварительно выбранный экземпляр (т.е. только на один).
Как предложено @xadm, ключ для «объединения» данных из нескольких схем в единый набор данных используется пользовательская логика выборки c для Link, используемой для удаленной схемы, как объяснено:
1) Определите пользовательскую функцию выборки, соответствующую потребностям вашего бизнеса (упрощенный пример):
const customFetch = async (uri, options) => {
// do not merge introspection query results!!!
// for introspection query always use predefined (first?) instance
if( operationType === 'IntrospectionQuery'){
return fetch(services[0].uri, options);
}
// array fecth calls to different endpoints
const calls = [
fetch(services[0].uri, options),
fetch(services[1].uri, options),
fetch(services[2].uri, options),
...
];
// execute calls in parallel
const data = await Promise.all(fetchCalls);
// do whatever you need to merge data according to your needs
const retData = customBusinessLogic();
// return new response containing merged data
return new fetch.Response(JSON.stringify(retData),{ "status" : 200 });
}
2) Определить ссылку с помощью пользовательской функции выборки. Если вы используете идентичные схемы, вам не нужно создавать ссылки на каждый экземпляр, достаточно одной.
const httpLink = new HttpLink(services[0].uri, fetch: customFetch });
3) Используйте Link для создания удаленной исполняемой схемы:
const schema = await introspectSchema(httpLink );
return makeRemoteExecutableSchema({
schema,
link: httpLink,
context: ({ req }) => {
// inject http request headers into context if you need them
return {
headers: {
...req.headers,
}
}
},
})
4) Если вы хотите перенаправить заголовки http полностью в функцию выборки, используйте apollo ContextLink:
// link for forwarding headers through context
const contextLink = setContext( (request, previousContext) => {
if( previousContext.graphqlContext ){
return {
headers: {
...previousContext.graphqlContext.headers
}
}
}
}).concat(http);
Просто упомяните, что для этого используются зависимости:
const { introspectSchema, makeRemoteExecutableSchema, ApolloServer } = require('apollo-server');
const fetch = require('node-fetch');
const { setContext } = require('apollo-link-context');
const { HttpLink } = require('apollo-link-http');
Я надеюсь, что это будет кому-то полезно ...