Реалізація GraphQL Persisted Queries для оптимізації

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Пропоновані послуги
Показано 1 з 1 послугУсі 2065 послуг
Реалізація GraphQL Persisted Queries для оптимізації
Середня
від 1 робочого дня до 3 робочих днів
Часті питання

Наші компетенції:

Етапи розробки
Останні роботи
  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    874
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851

GraphQL персистентні запити

Persisted Queries—техніка, при якій клієнт відправляє хеш запиту замість повного тіла. Сервер кешує запити за хешем. Переваги: зменшений трафік (особливо на mobile), можливість GET-запитів для кешування на CDN, захист від довільних запитів у продакшені.

Як працює Automatic Persisted Queries (APQ)

Клієнт          Сервер          CDN/Cache
  │                │                │
  │ POST {hash}    │                │
  │───────────────>│                │
  │ 404 Not Found  │                │
  │<───────────────│                │
  │                │                │
  │ POST {hash + query body}        │
  │───────────────>│                │
  │ {data} [зберегти hash→query]    │
  │<───────────────│                │
  │                │                │
  │ GET ?hash=...  │                │
  │──────────────────────────────>  │
  │            {data} з кешу        │
  │<──────────────────────────────  │

Apollo Client: налаштування APQ

import { ApolloClient, InMemoryCache, createHttpLink } from '@apollo/client'
import { createPersistedQueryLink } from '@apollo/client/link/persisted-queries'
import { generatePersistedQueryIdsFromManifest } from '@apollo/persisted-query-lists'
import { sha256 } from 'crypto-hash'

// Підхід 1: Automatic Persisted Queries (fallback при промахі кешу)
const persistedQueryLink = createPersistedQueryLink({
  sha256,
  useGETForHashedQueries: true  // GET запити для CDN кешування
})

const httpLink = createHttpLink({
  uri: 'https://api.example.com/graphql'
})

const client = new ApolloClient({
  link: persistedQueryLink.concat(httpLink),
  cache: new InMemoryCache()
})

Серверна підтримка APQ

// Вбудована підтримка APQ в Apollo Server
import { ApolloServer } from '@apollo/server'
import { createClient } from 'redis'
import { BaseRedisCache } from 'apollo-server-cache-redis'

const redis = createClient({ url: process.env.REDIS_URL })
await redis.connect()

const server = new ApolloServer({
  typeDefs,
  resolvers,

  // APQ cache: in-memory за замовчуванням, Redis у продакшені
  cache: new BaseRedisCache({
    client: redis,
    ttl: 86400  // 24 години
  }),

  // Включити APQ (за замовчуванням включено)
  persistedQueries: {
    ttl: 86400  // Час життя в кеші
  }
})

Registered Persisted Queries (безпечніший підхід)

APQ дозволяє виконувати будь-який запит після реєстрації. Registered PQ дозволяє тільки заранее відомі запити:

# Генерування маніфесту з клієнтських операцій (при збиранні)
npx generate-persisted-query-manifest \
  --documents "src/**/*.graphql" \
  --output persisted-query-manifest.json
// persisted-query-manifest.json
{
  "format": "apollo-persisted-query-manifest",
  "version": 1,
  "operations": [
    {
      "id": "dc67510fb4289672bea757e862d6b00e...",
      "name": "GetPosts",
      "type": "query",
      "body": "query GetPosts($limit: Int) { posts(first: $limit) { ... } }"
    },
    {
      "id": "e8c72e4d9b1a2f8e5c3d7a9b1f4e8c9d...",
      "name": "CreatePost",
      "type": "mutation",
      "body": "mutation CreatePost($input: CreatePostInput!) { createPost(input: $input) { ... } }"
    }
  ]
}
// Сервер валідує проти маніфесту
import { ApolloServer } from '@apollo/server'

const allowedQueries = new Set(
  manifest.operations.map(op => op.id)
)

const server = new ApolloServer({
  typeDefs,
  resolvers,
  persistedQueries: {
    ttl: 86400
  },
  // Дозволити тільки зареєстровані запити
  plugins: [{
    async requestDidResolveOperation({ request }) {
      const id = request.http?.headers?.get('x-graphql-query-id')
      if (id && !allowedQueries.has(id)) {
        throw new Error('Persisted query not found')
      }
    }
  }]
})

Переваги

  • Зменшений трафік: на 50-70% менші запити на mobile
  • Кешування CDN: GET запити можуть кешуватися стандартним CDN
  • Whitelisting запитів: запобігає небажаним запитам у продакшені
  • Захист від DDoS: тільки відомі запити виконуються на сервері

Терміни

Реалізація APQ (автоматичний підхід): 1–2 дні. Registered PQ з генерацією маніфесту та інтеграцією CI/CD: 2–3 дні.