GraphQL клиенты

Preact, благодаря своей лёгкой архитектуре и совместимости с React API, отлично сочетается с современными GraphQL клиентами. GraphQL клиент — это инструмент для упрощённого взаимодействия с GraphQL-сервером, позволяющий отправлять запросы, мутации и подписки, а также управлять локальным состоянием данных.

Выбор GraphQL клиента

Наиболее популярные клиенты для Preact:

  • Apollo Client: Полнофункциональный клиент с кэшированием, поддержкой подписок и мощными инструментами для оптимизации запросов.
  • urql: Лёгкий и гибкий клиент с минимальным размером пакета, легко интегрируется в Preact через preact/compat.
  • Relay: Оптимизированный для крупных приложений, хорошо подходит для работы с сложными схемами GraphQL, однако требует строгой структуры данных.

Интеграция Apollo Client с Preact

Для работы с Apollo в Preact используется совместимость через preact/compat, что позволяет использовать React-хуки и компоненты без изменений.

Установка зависимостей:
npm install @apollo/client graphql
npm install preact/compat
Настройка Apollo Client:
import { h } from 'preact';
import { ApolloClient, InMemoryCache, ApolloProvider } from '@apollo/client';
import App from './App';

const client = new ApolloClient({
  uri: 'https://example.com/graphql',
  cache: new InMemoryCache(),
});

export default function Root() {
  return (
    <ApolloProvider client={client}>
      <App />
    </ApolloProvider>
  );
}

Отправка запросов с помощью хуков

Apollo предоставляет хуки useQuery и useMutation, которые позволяют управлять состоянием загрузки, ошибок и данных.

import { h } from 'preact';
import { useQuery, gql } from '@apollo/client';

const GET_USERS = gql`
  query GetUsers {
    users {
      id
      name
      email
    }
  }
`;

export default function UsersList() {
  const { loading, error, data } = useQuery(GET_USERS);

  if (loading) return <p>Загрузка...</p>;
  if (error) return <p>Ошибка: {error.message}</p>;

  return (
    <ul>
      {data.users.map(user => (
        <li key={user.id}>{user.name} — {user.email}</li>
      ))}
    </ul>
  );
}

Ключевые моменты при работе с хуками:

  • loading сигнализирует о процессе получения данных.
  • error содержит информацию о возможных сбоях запроса.
  • data — результат запроса, автоматически обновляемый при изменении кэша.

Управление кэшированием

InMemoryCache Apollo Client позволяет эффективно хранить результаты запросов для минимизации повторных запросов к серверу. Можно настраивать поля кэша, идентификаторы объектов и стратегии обновления данных:

const client = new ApolloClient({
  uri: 'https://example.com/graphql',
  cache: new InMemoryCache({
    typePolicies: {
      User: {
        keyFields: ['id'],
      },
    },
  }),
});

Использование мутаций

Мутации изменяют данные на сервере и позволяют обновлять кэш автоматически:

import { h } from 'preact';
import { useMutation, gql } from '@apollo/client';

const ADD_USER = gql`
  mutation AddUser($name: String!, $email: String!) {
    addUser(name: $name, email: $email) {
      id
      name
      email
    }
  }
`;

export default function AddUserForm() {
  const [addUser, { data, loading, error }] = useMutation(ADD_USER);

  const handleSubmit = async (event) => {
    event.preventDefault();
    const name = event.target.name.value;
    const email = event.target.email.value;

    await addUser({ variables: { name, email } });
  };

  return (
    <form onSub mit={handleSubmit}>
      <input name="name" placeholder="Имя" />
      <input name="email" placeholder="Email" />
      <button type="submit">Добавить</button>
      {loading && <p>Отправка...</p>}
      {error && <p>Ошибка: {error.message}</p>}
      {data && <p>Пользователь добавлен: {data.addUser.name}</p>}
    </form>
  );
}

Подписки и реальное время

Apollo Client поддерживает GraphQL подписки через WebSocket, что позволяет обновлять интерфейс в реальном времени:

import { WebSocketLink } from '@apollo/client/link/ws';
import { ApolloClient, InMemoryCache, split } from '@apollo/client';
import { getMainDefinition } from '@apollo/client/utilities';

const wsLink = new WebSocketLink({
  uri: 'wss://example.com/graphql',
  options: { reconnect: true },
});

const client = new ApolloClient({
  link: wsLink,
  cache: new InMemoryCache(),
});

Подписки интегрируются с хуками useSubscription, позволяя динамически отображать новые данные.

Альтернатива Apollo: urql

urql — более лёгкий вариант, минималистичный по функционалу, но с гибкой архитектурой. Настройка клиента и отправка запросов выглядят следующим образом:

import { createClient, Provider, useQuery } from 'urql';
import { h } from 'preact';

const client = createClient({ url: 'https://example.com/graphql' });

const GET_POSTS = `
  query {
    posts {
      id
      title
    }
  }
`;

function Posts() {
  const [result] = useQuery({ query: GET_POSTS });
  const { data, fetching, error } = result;

  if (fetching) return <p>Загрузка...</p>;
  if (error) return <p>Ошибка: {error.message}</p>;

  return (
    <ul>
      {data.posts.map(post => <li key={post.id}>{post.title}</li>)}
    </ul>
  );
}

export default function Root() {
  return (
    <Provider value={client}>
      <Posts />
    </Provider>
  );
}

urql обеспечивает поддержку хуков, кэширование и расширяемость через обмены (exchanges), что делает его удобным для небольших и средних приложений.

Особенности использования GraphQL клиентов в Preact

  • Preact полностью поддерживает React API через preact/compat, что упрощает интеграцию популярных клиентов.
  • Встроенные хуки и контексты позволяют организовывать глобальное состояние данных без сторонних библиотек.
  • Оптимизация рендеринга достигается использованием ключей и мемоизации компонентов через preact/hooks.

Практические рекомендации

  • Для больших приложений с сложными схемами лучше использовать Apollo Client с его мощной системой кэширования и подписок.
  • Для небольших проектов или когда важен минимальный размер бандла, предпочтительнее urql.
  • При использовании мутаций важно обновлять локальный кэш для согласованного отображения данных.
  • Подписки следует применять там, где требуется отображение данных в реальном времени, например, чаты или уведомления.

GraphQL клиенты в Preact позволяют организовать эффективное взаимодействие с сервером, поддерживать реактивность данных и минимизировать повторные запросы, сохраняя при этом лёгкость и высокую производительность интерфейсов.