Три кита интеграций: REST, GraphQL и gRPC в мире JavaScript
Разработка на JavaScript сегодня — это бесконечный обмен данными. Ваше приложение тянет курсы валют, отправляет формы, стримит видео или синхронизирует документы в реальном времени. И каждый раз вы выбираете, как именно ваш клиент будет общаться с сервером.
Долгое время стандартом был REST. Он прост, как молоток. Но для сложных проектов молотка мало — нужен швейцарский нож (GraphQL) или даже отбойный молоток (gRPC).
В этой статье мы разберём три главных подхода к работе с API на JavaScript. Вы увидите реальные примеры кода, поймёте сильные и слабые стороны каждого протокола и сможете осознанно выбрать инструмент для своего следующего проекта. Поехали!
REST API: классика, которая не умирает
REST (Representational State Transfer) — это архитектурный стиль, а не протокол. Большинство разработчиков под REST понимают HTTP-запросы к ресурсам (GET /users, POST /orders).
Как выглядит REST-запрос на JavaScript
Самый популярный способ — нативный fetch или библиотека axios. Вот типичный GET-запрос:
// Получаем список пользователей
const getUsers = async () => {
const response = await fetch('https://api.example.com/users');
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
return data;
};
// Пример использования
try {
const users = await getUsers();
console.log(users);
} catch (error) {
console.error('Ошибка при загрузке пользователей:', error);
}
Плюсы REST для JavaScript-разработчика
- Простота и предсказуемость. GET, POST, PUT, DELETE — каждый глагол имеет чёткий смысл.
- Кэширование. HTTP-кеш работает из коробки, что ускоряет повторные запросы.
- Широкая поддержка. Любой бэкенд на любом языке умеет отдавать REST.
- Инструменты. Postman, Swagger, Insomnia — огромная экосистема для тестирования.
Главные недостатки REST
- Over-fetching (избыточность данных). Вы запрашиваете /users, а сервер отдаёт все поля, включая пароль (хеш, конечно) и внутренние ID, хотя вам нужны только имя и email.
- Under-fetching (нехватка данных). Чтобы получить пользователя и его последние заказы, нужно сделать два запроса: /users/1 и /users/1/orders.
- Множество эндпоинтов. Сложная бизнес-логика плодит десятки URL, которые трудно поддерживать.
Когда выбирать REST? Идеально для простых CRUD-приложений, публичных API и проектов, где важна простота и кэширование.
GraphQL: запроси только то, что нужно
GraphQL — это язык запросов и среда выполнения, созданная Facebook (теперь Meta). Вместо множества эндпоинтов — один endpoint, а клиент сам решает, какие поля получить.
Пишем GraphQL-запрос на JavaScript
Для работы с GraphQL на клиенте чаще всего используют библиотеку @apollo/client или urql. Но можно и просто через fetch:
// GraphQL-запрос через fetch
const query = `
query {
user(id: "123") {
name
email
posts {
title
createdAt
}
}
}
`;
const fetchUserWithPosts = async () => {
const response = await fetch('https://api.example.com/graphql', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query })
});
const result = await response.json();
return result.data;
};
// Вызываем
fetchUserWithPosts().then(data => console.log(data));
Видите разницу? Мы в одном запросе получили и пользователя, и его посты, и только те поля, которые реально нужны. Никакого овер-фетчинга!
Сильные стороны GraphQL
- Точность данных. Клиент контролирует ответ сервера.
- Один эндпоинт. Вся работа через /graphql.
- Сильная типизация. Схема определяет все типы, поля и связи — это упрощает документацию и разработку.
- Подписки (Subscriptions). WebSocket-соединения для real-time данных (чат, уведомления).
Когда GraphQL может быть неудобен
- Сложность кэширования. HTTP-кеш не работает, нужно использовать Apollo Cache или ручное кэширование.
- Производительность запросов. Злонамеренный клиент может запросить глубоко вложенные данные и положить сервер (нужна защита, depth limiting).
- Избыточность для простых API. Если у вас 3 модели и 5 запросов — REST будет проще.
Когда выбирать GraphQL? Для сложных интерфейсов с динамическими данными (дашборды, соцсети, маркетплейсы), где важна гибкость запросов.
gRPC: скорость и строгость для микросервисов
gRPC (Google Remote Procedure Call) — это высокопроизводительный RPC-фреймворк. Он использует Protocol Buffers (Protobuf) для сериализации данных и HTTP/2 для транспорта.
В мире JavaScript gRPC чаще всего применяется для связи между микросервисами на Node.js. Клиентская сторона (браузер) поддерживается хуже, но для server-to-server это мощный инструмент.
Пример gRPC на Node.js
Сначала определим proto-файл (описание сервиса):
// user.proto
syntax = "proto3";
service UserService {
rpc GetUser (GetUserRequest) returns (User);
}
message GetUserRequest {
string user_id = 1;
}
message User {
string id = 1;
string name = 2;
string email = 3;
}
Теперь сервер на Node.js:
const grpc = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');
const packageDefinition = protoLoader.loadSync('user.proto');
const userProto = grpc.loadPackageDefinition(packageDefinition).UserService;
const server = new grpc.Server();
server.addService(userProto.service, {
GetUser: (call, callback) => {
const userId = call.request.user_id;
// Логика получения пользователя из БД
const user = { id: userId, name: 'Alice', email: 'alice@example.com' };
callback(null, user);
}
});
server.bindAsync('0.0.0.0:50051', grpc.ServerCredentials.createInsecure(), () => {
console.log('gRPC server running on port 50051