Реалізація GraphQL Federation для об'єднання мікросервісів
Уявіть: фронтенд-команда витрачає години на координацію з бекендерами, щоб зібрати одну сторінку. Кожен мікросервіс віддає дані у своєму форматі — доводиться робити 5–10 запитів до різних API. Виникають N+1 проблеми, latency зростає, кешування перетворюється на головний біль. На одному з проєктів ми скоротили кількість запитів з 12 до 2, впровадивши Federation. Наш досвід — 7+ років у розподілених системах, понад 50 продакшен-впроваджень GraphQL. Федерація — це не просто gateway, а декларативний підхід: кожна команда описує, як її мікросервіс розширює загальний граф даних. На відміну від ручного агрегування, Federation автоматично будує оптимальний план виконання, використовуючи @key та @requires.
Як об'єднати мікросервіси за допомогою GraphQL Federation?
Federation дозволяє об'єднати декілька незалежних GraphQL-сервісів (subgraph) в єдиний API. Клієнт робить один запит до Federation Gateway (Apollo Router), який збирає дані з різних subgraph і повертає єдину відповідь. Кожна команда володіє своїм subgraph і деплоїть його незалежно — без блокувань і узгоджень. Детальна специфікація доступна в документації Apollo Federation.
Архітектура Federation:
- Клієнт (браузер/мобільний) → Federation Gateway (Apollo Router / Apollo Gateway)
- User Subgraph (Node.js) → Postgres
- Order Subgraph (Go) → Postgres
- Product Subgraph (Python) → MongoDB
- Review Subgraph (Node.js) → Postgres
Subgraph: User Service — приклад реалізації
// user-service/schema.ts import { buildSubgraphSchema } from '@apollo/subgraph'; import { gql } from 'graphql-tag'; const typeDefs = gql` extend schema @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@key", "@shareable"]) type User @key(fields: "id") { id: ID! name: String! email: String! createdAt: DateTime! } type Query { me: User user(id: ID!): User } `; const resolvers = { User: { __resolveReference: async ({ id }) => { return userRepository.findById(id); } }, Query: { me: (_, __, { userId }) => userRepository.findById(userId), user: (_, { id }) => userRepository.findById(id) } }; export const schema = buildSubgraphSchema({ typeDefs, resolvers });Subgraph: Order Service — розширення типів
// order-service/schema.ts const typeDefs = gql` extend schema @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@key", "@external", "@requires"]) type Order @key(fields: "id") { id: ID! status: OrderStatus! total: Float! items: [OrderItem!]! customer: User! createdAt: DateTime! } type User @key(fields: "id") { id: ID! @external orders(limit: Int = 10): [Order!]! orderStats: OrderStats! } type OrderStats { totalOrders: Int! totalSpent: Float! lastOrderAt: DateTime } enum OrderStatus { PENDING PAID SHIPPED DELIVERED CANCELLED } type Query { order(id: ID!): Order orders(customerId: ID, status: OrderStatus): [Order!]! } `; const resolvers = { User: { __resolveReference: async ({ id }) => ({ id }), orders: async ({ id }, { limit }) => orderRepository.findByCustomerId(id, limit), orderStats: async ({ id }) => orderRepository.getStatsForCustomer(id) }, Order: { __resolveReference: async ({ id }) => orderRepository.findById(id), customer: ({ customerId }) => ({ __typename: 'User', id: customerId }) } };Apollo Router (Federation Gateway) — конфігурація
# router.yaml federation_version: 2.3 supergraph: listen: 0.0.0.0:4000 subgraphs: users: routing_url: http://user-service:4001/graphql orders: routing_url: http://order-service:4002/graphql products: routing_url: http://product-service:4003/graphql cors: origins: - https://app.example.com headers: all: request: - propagate: named: Authorization - propagate: named: X-Correlation-IdЗапуск через Docker:
docker run -p 4000:4000 -v $(pwd)/router.yaml:/dist/config/router.yaml -e APOLLO_KEY=service:my-graph:xxx -e APOLLO_GRAPH_REF=my-graph@production ghcr.io/apollographql/router:latest.Що дає Federation порівняно з REST і звичайним Gateway?
Характеристика Federation REST-агрегатор Звичайний Gateway Кількість запитів 1 5–10 1 (але дані збираються послідовно) Час відповіді ~50 мс (паралельні запити) ~200 мс ~100–150 мс (послідовно) Незалежність команд ✅ Кожна команда володіє subgraph ❌ Спільна кодова база ❌ Спільна кодова база Зміна схеми Без блокувань Узгодження Узгодження Кешування На рівні subgraph HTTP-кеш Централізоване Federation дозволяє підвищити продуктивність у 2–3 рази порівняно з REST-агрегатором за рахунок паралельної вибірки та кешування на рівні subgraph. На одному проєкті ми знизили час завантаження сторінки з 2.3 до 0.8 секунди — це в 2.9 рази швидше.
Інструмент Призначення Розповсюдження Apollo Router Federation Gateway, паралельний збір даних Open source + Managed Apollo Rover CLI Публікація та перевірка схем Open source Apollo Studio Реєстр схем, моніторинг SaaS Managed Federation (Apollo Studio)
При Managed Federation схеми subgraph публікуються в Apollo Studio Registry. Router завантажує актуальну supergraph-схему автоматично при зміні будь-якого subgraph. Публікація з перевіркою сумісності виконується через
rover subgraph check.# В CI/CD пайплайні rover subgraph publish my-graph@production \ --schema ./schema.graphql \ --name orders \ --routing-url http://order-service:4002/graphqlАвторизація на рівні subgraph
Кожен subgraph самостійно перевіряє права. Приклад на TypeScript: в ресолвері Order
__resolveReferenceперевіряється, що поточний користувач — власник замовлення або має роль admin. У разі відмови повертається помилкаForbiddenError.Чому Federation варто обрати для нового проєкту?
Federation дає незалежність командам, атомарні деплої та автоматичну перевірку сумісності. Ми гарантуємо, що схема залишиться консистентною при кожній зміні. Це найкраще рішення для компаній з 3+ мікросервісами, де важлива швидкість змін.
Що входить в роботу?
- Аудит поточної архітектури та виділення меж subgraph.
- Проектування supergraph-схеми з @key та @requires.
- Реалізація subgraph-сервісів (Node.js, Go, Python — будь-який стек).
- Налаштування Apollo Router з CORS, авторизацією, моніторингом.
- Інтеграція Managed Federation з CI-пайплайном перевірки сумісності.
- Документація по схемі та точках розширення.
- Навчання команди роботі з Federation.
- Підтримка на старті: 2 тижні після запуску.
Процес роботи та терміни
- Аналіз — виділяємо межі subgraph, визначаємо точки інтеграції з legacy.
- Проектування — описуємо supergraph-схему, узгоджуємо @key та @requires.
- Розробка — кожен subgraph створюється як окремий сервіс з власним деплоєм.
- Налаштування Router — конфігурація CORS, авторизації, моніторингу (Apollo Studio).
- Managed Federation — підключаємо CI-пайплайн з перевіркою сумісності.
- Тестування — навантажувальне тестування та E2E-тести.
- Запуск — покроковий rollout з моніторингом помилок.
Терміни реалізації:
- 2–3 subgraph з базовою Federation — 2–3 тижні.
- Apollo Router + Managed Federation + CI-перевірки сумісності — ще 1 тиждень.
- Складні @requires, @provides, nested resolvers — 1–2 додаткові тижні.
Вартість розраховується індивідуально після аналізу вашого проєкту. Орієнтовний бюджет від $5000 для базового впровадження. Отримайте консультацію — ми оцінимо обсяг роботи і запропонуємо оптимальне рішення. Команда має 7+ років досвіду та виконала 50+ проєктів. Замовте впровадження Federation: зв'яжіться з нами — підготуємо пропозицію під ключ. Ваша архітектура стане гнучкою та масштабованою без зайвих витрат.
Приклад детальної реалізації subgraph на TypeScript
Весь код User та Order subgraph доступний у репозиторії. При необхідності адаптуємо під ваш стек.Отримайте консультацію по впровадженню Federation — напишіть нам, і ми оцінимо ваш проєкт.







