Для интеграции с GraphQL в приложении на JavaScript используется библиотека Apollo Client. Начинается работа с установкой необходимых пакетов:
npm install @apollo/client graphql
@apollo/client содержит основной функционал для работы с
GraphQL, включая кэширование, управление состоянием и работу с
подписками. Пакет graphql необходим для корректного
парсинга запросов и мутаций.
После установки создается клиент:
import { ApolloClient, InMemoryCache, HttpLink } from '@apollo/client';
const client = new ApolloClient({
link: new HttpLink({ uri: 'https://example.com/graphql' }),
cache: new InMemoryCache(),
});
HttpLink — настраивает конечную точку
GraphQL.InMemoryCache — реализует кэширование
запросов и оптимизацию повторных запросов.Для интеграции Apollo Client с React-приложением применяется
компонент ApolloProvider. Он обеспечивает
доступ к клиенту во всех дочерних компонентах:
import { ApolloProvider } from '@apollo/client';
import App from './App';
<ApolloProvider client={client}>
<App />
</ApolloProvider>
Все компоненты, использующие GraphQL-запросы, должны находиться
внутри ApolloProvider, чтобы получить
доступ к клиенту.
Основной инструмент получения данных — хук
useQuery:
import { useQuery, gql } from '@apollo/client';
const GET_USERS = gql`
query GetUsers {
users {
id
name
email
}
}
`;
function UsersList() {
const { data, loading, error } = 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>
);
}
gql — тег для определения
GraphQL-запроса.loading — состояние загрузки.error — информация об ошибках.data — возвращаемые данные.Для изменения данных используется
useMutation:
import { useMutation, gql } from '@apollo/client';
const ADD_USER = gql`
mutation AddUser($name: String!, $email: String!) {
addUser(name: $name, email: $email) {
id
name
email
}
}
`;
function AddUserForm() {
const [addUser, { data, loading, error }] = useMutation(ADD_USER);
const handleSubmit = async (e) => {
e.preventDefault();
const form = e.target;
const name = form.name.value;
const email = form.email.value;
await addUser({ variables: { name, email } });
form.reset();
};
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>}
</form>
);
}
variables — объект с параметрами
запроса.InMemoryCache позволяет настраивать стратегию кэширования:
const client = new ApolloClient({
link: new HttpLink({ uri: '/graphql' }),
cache: new InMemoryCache({
typePolicies: {
User: {
keyFields: ['id'],
},
Query: {
fields: {
users: {
merge(existing = [], incoming) {
return [...existing, ...incoming];
},
},
},
},
},
}),
});
typePolicies — правила для конкретных
типов данных.keyFields — уникальные идентификаторы
объектов.merge — стратегия объединения новых и
старых данных при повторных запросах.Для реализации real-time обновлений используется Apollo Client + WebSocket:
import { ApolloClient, InMemoryCache, split, HttpLink } from '@apollo/client';
import { GraphQLWsLink } from '@apollo/client/link/subscriptions';
import { createClient } from 'graphql-ws';
import { getMainDefinition } from '@apollo/client/utilities';
const httpLink = new HttpLink({ uri: '/graphql' });
const wsLink = new GraphQLWsLink(createClient({ url: 'ws://localhost:4000/graphql' }));
const splitLink = split(
({ query }) => {
const definition = getMainDefinition(query);
return definition.kind === 'OperationDefinition' && definition.operation === 'subscription';
},
wsLink,
httpLink
);
const client = new ApolloClient({
link: splitLink,
cache: new InMemoryCache(),
});
split — выбирает подходящий транспорт
для запросов и подписок.GraphQLWsLink — устанавливает
соединение через WebSocket.Apollo Client позволяет автоматически обновлять кэш после мутаций:
const [addUser] = useMutation(ADD_USER, {
update(cache, { data: { addUser } }) {
const existing = cache.readQuery({ query: GET_USERS });
cache.writeQuery({
query: GET_USERS,
data: { users: [...existing.users, addUser] },
});
},
});
update — функция для изменения кэша
после выполнения мутации.readQuery и
writeQuery для синхронизации локального
состояния с сервером.Для мгновенной реакции UI можно использовать optimisticResponse:
const [addUser] = useMutation(ADD_USER, {
optimisticResponse: {
addUser: {
id: -1,
name: 'Загрузка...',
email: 'loading@example.com',
__typename: 'User',
},
},
});
id временное, чтобы избежать конфликтов с
реальными объектами.useLazyQuery позволяет запускать запрос не при рендере, а по событию:
const [getUsers, { data, loading, error }] = useLazyQuery(GET_USERS);
<button onCl ick={() => getUsers()}>Загрузить пользователей</button>
Apollo Client предоставляет гибкую обработку ошибок:
const { error } = useQuery(GET_USERS, {
onError(err) {
console.error('Ошибка запроса:', err);
},
});
Apollo Client обеспечивает полный цикл работы с GraphQL:
useQuery,
useMutation.InMemoryCache и политиками типов.Эти возможности делают библиотеку незаменимым инструментом для современных React-приложений, где требуется гибкая работа с серверными данными и синхронизация UI.