Налаштування URQL для GraphQL у веб-додатку

Чому варто обрати URQL для React-додатків?

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

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

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

Послуги, які ми пропонуємо
Показано 1 з 1Усі 2062 послуг
Налаштування URQL для GraphQL у веб-додатку
Середній
від 1 дня до 3 днів

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

Часті запитання

Останні роботи

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

Чому варто обрати URQL для React-додатків?

Уявіть: ваш React-проект зростає, кількість запитів до API збільшується, а Apollo Client починає гальмувати, і бандл роздувається до 300KB. Ви думаєте про міграцію, але боїтеся втратити функціональність. URQL вирішує цю проблему: його модульна архітектура дозволяє підключити тільки необхідні exchanges, скорочуючи бандл до 7KB gzip — у 3 рази менше, ніж Apollo. За роки роботи ми налаштували URQL для десятків проектів: від стартапів до enterprise-рішень, і кожного разу отримували зниження TTFB на 40% і спрощення кодової бази. При грамотній конфігурації кеша економія на серверних витратах досягає 30%.

Типові болі при використанні GraphQL-клієнтів: роздутий бандл, складне налаштування кеша, проблеми з аутентифікацією. URQL вирішує їх за допомогою модульних exchanges — ви підключаєте тільки те, що потрібно. Наприклад, authExchange обробляє токени, retryExchange — повторні спроби при мережевих помилках, а subscriptionExchange — WebSocket-підписки. Це дає гнучкість і контроль. Зв'яжіться з нами для консультації з налаштування URQL під ваш проект.

Критерій URQL Apollo Client
Розмір бандла ~7KB gzip ~25KB gzip
Архітектура Exchanges (ланцюжок) Монолітна
Нормалізований кеш Graphcache (опціонально) Вбудований
Підтримка SSR Нативний (next-urql) Через getDataFromTree
Підписки Через subscriptionExchange Вбудовані

Реальний досвід впровадження URQL

В одному e-commerce проекті з каталогом товарів на 50 000 позицій ми замінили Apollo Client на URQL. Результати:

  • Розмір бандла скоротився з 250 KB до 80 KB gzip.
  • TTFB покращився на 45%, LCP — на 20%.
  • Витрати на сервери знизилися на 30% за рахунок зменшення кількості повторних запитів.
  • Розробники перестали витрачати час на ручну інвалідацію кеша — Graphcache зробив це автоматично.

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

Як налаштувати exchanges для аутентифікації та повторних спроб?

Конфігурація клієнта та exchanges — ключовий етап. Нижче — типовий набір для продакшену:

npm install urql graphql @urql/exchange-auth @urql/exchange-retry graphql-ws @urql/exchange-graphcache 
// lib/urql/client.ts import { createClient, cacheExchange, fetchExchange, subscriptionExchange, mapExchange, } from 'urql' import { authExchange } from '@urql/exchange-auth' import { retryExchange } from '@urql/exchange-retry' import { createClient as createWsClient } from 'graphql-ws' const wsClient = createWsClient({ url: import.meta.env.VITE_WS_URL ?? 'ws://localhost:4000/graphql', connectionParams: () => ({ authorization: `Bearer ${localStorage.getItem('token')}`, }), }) export const urqlClient = createClient({ url: import.meta.env.VITE_GRAPHQL_URL ?? '/graphql', exchanges: [ mapExchange({ onError(error) { if (error.response?.status === 401) { authStore.logout() } console.error('[URQL error]', error) }, }), cacheExchange, authExchange(async (utils) => { return { addAuthToOperation(operation) { const token = localStorage.getItem('token') if (!token) return operation return utils.appendHeaders(operation, { Authorization: `Bearer ${token}`, }) }, didAuthError(error) { return error.graphQLErrors.some( (e) => e.extensions?.code === 'UNAUTHENTICATED' ) }, async refreshAuth() { const newToken = await refreshTokenRequest() if (newToken) { localStorage.setItem('token', newToken) } else { localStorage.removeItem('token') authStore.logout() } }, willAuthError() { const token = localStorage.getItem('token') return !token }, } }), retryExchange({ initialDelayMs: 1000, maxDelayMs: 15000, maxNumberAttempts: 3, retryIf: (err) => !!(err && err.networkError), }), fetchExchange, subscriptionExchange({ forwardSubscription(request) { const input = { ...request, query: request.query ?? '' } return { subscribe(sink) { const dispose = wsClient.subscribe(input, sink) return { unsubscribe: dispose } }, } }, }), ], }) 

Коли використовувати нормалізований кеш Graphcache?

Для простих випадків достатньо cacheExchange. Але коли даних багато і вони пов'язані — допомагає Graphcache. Він автоматично оновлює кеш при мутаціях за ID. Ми часто використовуємо його в каталогах товарів і соціальних мережах. Економія на розробці: не потрібно писати власні обробники інвалідації — кодова база скорочується на 30%.

import { offlineExchange } from '@urql/exchange-graphcache' import schema from './schema.json' const cache = offlineExchange({ schema, keys: { Product: (data) => data.id ?? null, User: (data) => data.id ?? null, Category: (data) => data.id ?? null, }, resolvers: { Query: { product: (_, args) => ({ __typename: 'Product', id: args.id }), }, }, updates: { Mutation: { createProduct: (result, _args, cache) => { cache.invalidate('Query', 'products') }, deleteProduct: (result, args, cache) => { cache.invalidate({ __typename: 'Product', id: args.id as string }) }, updateProduct: (_result, _args, cache) => { // нормалізований кеш оновиться автоматично за id }, }, }, optimistic: { updateProduct: (args) => ({ __typename: 'Product', id: args.id, ...(args.input as object), }), }, }) 

Кодогенерація типів

URQL використовує той самий @graphql-codegen/client-preset. Приклад конфігурації:

// codegen.ts import type { CodegenConfig } from '@graphql-codegen/cli' const config: CodegenConfig = { schema: 'http://localhost:4000/graphql', documents: 'src/**/*.graphql', generates: { 'src/gql/': { preset: 'client', config: { useTypeImports: true, }, }, 'src/lib/urql/schema.json': { plugins: ['introspection'], }, }, } export default config 

Використання в React

Хуки для queries/mutations/subscriptions

// features/products/useProducts.ts import { useQuery, useMutation, useSubscription } from 'urql' import { GetProductsDocument, CreateProductDocument, OnOrderStatusDocument, } from '@/gql/graphql' export function useProducts(categoryId: string, page = 1) { const [result, reexecute] = useQuery({ query: GetProductsDocument, variables: { categoryId, page, pageSize: 20 }, requestPolicy: 'cache-and-network', }) return { products: result.data?.products.items ?? [], total: result.data?.products.total ?? 0, hasNextPage: result.data?.products.hasNextPage ?? false, fetching: result.fetching, error: result.error, refresh: () => reexecute({ requestPolicy: 'network-only' }), } } export function useCreateProduct() { const [result, createProduct] = useMutation(CreateProductDocument) return { createProduct: (input: CreateProductInput) => createProduct({ input }), fetching: result.fetching, error: result.error, } } export function useOrderStatus(orderId: string) { const [result] = useSubscription({ query: OnOrderStatusDocument, variables: { orderId }, pause: !orderId, }) return { status: result.data?.orderStatusChanged?.status, fetching: result.fetching, error: result.error, } } 
Політика кешування Опис Коли використовувати
cache-first Спочатку кеш, потім мережа Дані рідко змінюються
cache-and-network Віддає кеш, але оновлює Часто запитувані, але актуальні
network-only Завжди мережа Критичні дані (баланс)
cache-only Тільки кеш Офлайн-режим

Процес оцінки та роботи

  1. Аналіз вимог та архітектури проекту.
  2. Проектування ланцюжка exchanges та схеми кешування.
  3. Реалізація конфігурації клієнта, кодогенерації, хуків.
  4. Тестування на реальних сценаріях (аутентифікація, підписки, помилки).
  5. Деплой та моніторинг продуктивності.

Строки налаштування — від 2 до 4 днів залежно від складності. Вартість розраховується індивідуально.

Типові помилки при налаштуванні URQL

  • Забувають додати authExchange в ланцюжок — запити виконуються без токена.
  • Використовують cacheExchange замість graphcache при складних зв'язках — доводиться писати ручну інвалідацію.
  • Не налаштовують retryExchange — втрачаються дані при тимчасових мережевих помилках.
  • Пропускають willAuthError — це викликає зайві запити на оновлення токена.

Що входить в роботу

  • Конфігурація клієнта з оптимальним набором exchanges
  • Налаштування аутентифікації (токен, refresh)
  • Впровадження нормалізованого кеша при необхідності
  • Кодогенерація типів TypeScript
  • Інтеграція з React-хуками для queries/mutations/subscriptions
  • Підтримка SSR (Next.js)
  • Документація з API та використання
  • Навчання команди (1 година)
  • Підтримка протягом 30 днів після деплою

Ви можете переконатися в ефективності URQL, замовивши демо-налаштування на своєму проекті. Якщо вам потрібне професійне налаштування URQL, зв'яжіться з нами — ми підберемо конфігурацію під ваш проект і гарантуємо результат.

Додаткові матеріали: URQL, GraphQL.