← Назад к вопросам
Какие использовал способы взаимодействия с Backend?
1.7 Middle🔥 181 комментариев
#JavaScript Core
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Способы взаимодействия с Backend
1. Fetch API (современный стандарт)
Fetch API — встроенный в браузер способ делать HTTP запросы. Это переход от старого XMLHttpRequest.
// Простой GET запрос
fetch("/api/v1/users")
.then((response) => {
if (!response.ok) throw new Error(`HTTP ${response.status}`);
return response.json();
})
.then((data) => console.log("Users:", data))
.catch((error) => console.error("Error:", error));
// POST запрос с данными
fetch("/api/v1/users", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer " + token,
},
body: JSON.stringify({ name: "John", email: "john@example.com" }),
})
.then((response) => response.json())
.then((user) => console.log("Created:", user));
// Timeout и abort
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 5000);
fetch("/api/v1/data", { signal: controller.signal })
.then((response) => response.json())
.finally(() => clearTimeout(timeoutId));
2. Async/Await (синтаксический сахар над Promises)
// Асинхронная функция с await
async function getUser(userId) {
try {
const response = await fetch(`/api/v1/users/${userId}`);
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const user = await response.json();
return user;
} catch (error) {
console.error("Failed to fetch user:", error);
throw error;
}
}
// Использование
const user = await getUser(123);
console.log(user);
// Параллельные запросы
const [users, posts] = await Promise.all([
fetch("/api/v1/users").then((r) => r.json()),
fetch("/api/v1/posts").then((r) => r.json()),
]);
3. XMLHttpRequest (старый подход, не рекомендуется)
// Старый способ — избегай его
const xhr = new XMLHttpRequest();
xhr.open("GET", "/api/v1/users", true);
xhr.responseType = "json";
xhr.onload = () => {
if (xhr.status === 200) {
console.log("Data:", xhr.response);
}
};
xhr.onerror = () => {
console.error("Network error");
};
xhr.send();
Problems: verbose, callback hell, сложно обрабатывать ошибки.
4. Библиотеки для HTTP запросов
Axios
import axios from "axios";
// Создание клиента с дефолтными параметрами
const api = axios.create({
baseURL: "https://api.example.com",
timeout: 10000,
headers: { "X-Custom-Header": "value" },
});
// Автоматическое добавление токена ко всем запросам
api.interceptors.request.use((config) => {
const token = localStorage.getItem("token");
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
});
// Обработка ошибок глобально
api.interceptors.response.use(
(response) => response.data,
(error) => {
if (error.response?.status === 401) {
// Перенаправить на логин
}
return Promise.reject(error);
}
);
// Использование
const user = await api.get(`/users/${id}`);
const newUser = await api.post("/users", { name: "John" });
TanStack Query (React Query)
import { useQuery, useMutation } from "@tanstack/react-query";
function UserProfile({ userId }) {
// Автоматический кеш, рефетч, загрузка ошибок
const { data: user, isLoading, error } = useQuery({
queryKey: ["users", userId],
queryFn: async () => {
const response = await fetch(`/api/v1/users/${userId}`);
return response.json();
},
});
// Мутация (POST/PUT/DELETE)
const updateMutation = useMutation({
mutationFn: async (updates) =>
fetch(`/api/v1/users/${userId}`, {
method: "PUT",
body: JSON.stringify(updates),
}).then((r) => r.json()),
onSuccess: () => {
// Автоматический рефетч или ручное обновление кеша
queryClient.invalidateQueries(["users", userId]);
},
});
if (isLoading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
return (
<div>
<h1>{user.name}</h1>
<button onClick={() => updateMutation.mutate({ name: "Jane" })}>
Update
</button>
</div>
);
}
SWR (Stale-While-Revalidate)
import useSWR from "swr";
const fetcher = (url) => fetch(url).then((r) => r.json());
function UserList() {
const { data: users, error } = useSWR("/api/v1/users", fetcher);
if (error) return <div>Failed to load</div>;
if (!users) return <div>Loading...</div>;
return (
<ul>
{users.map((user) => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
}
5. GraphQL
import { gql, useQuery } from "@apollo/client";
const GET_USER = gql`
query GetUser($id: ID!) {
user(id: $id) {
id
name
email
posts {
id
title
}
}
}
`;
function UserProfile({ userId }) {
const { loading, error, data } = useQuery(GET_USER, {
variables: { id: userId },
});
if (loading) return <p>Loading...</p>;
if (error) return <p>Error: {error.message}</p>;
return (
<div>
<h1>{data.user.name}</h1>
<ul>
{data.user.posts.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
</div>
);
}
Преимущества GraphQL:
- Запрашиваешь только нужные данные (no over-fetching)
- Одна точка входа (не нужно знать все endpoints)
- Сильная типизация
6. WebSocket (реал-тайм коммуникация)
// Нативный WebSocket
const socket = new WebSocket("wss://api.example.com/chat");
socket.onopen = () => {
console.log("Connected");
socket.send(JSON.stringify({ type: "subscribe", channel: "news" }));
};
socket.onmessage = (event) => {
const message = JSON.parse(event.data);
console.log("Message:", message);
};
socket.onerror = (error) => console.error("Error:", error);
socket.onclose = () => console.log("Disconnected");
// Отправка сообщения
socket.send(JSON.stringify({ type: "message", text: "Hello!" }));
Socket.io (удобнее, с фолбеком на polling)
import io from "socket.io-client";
const socket = io("https://api.example.com", {
reconnection: true,
reconnectionDelay: 1000,
reconnectionDelayMax: 5000,
});
socket.on("connect", () => console.log("Connected"));
socket.on("message", (data) => console.log("Got:", data));
socket.emit("send-message", { text: "Hello" });
7. Server-Sent Events (SSE)
// Одностороннее подключение от сервера к клиенту
const eventSource = new EventSource("/api/v1/stream");
eventSource.addEventListener("update", (event) => {
const data = JSON.parse(event.data);
console.log("Update:", data);
});
eventSource.onerror = () => {
console.error("Connection lost");
eventSource.close();
};
Этто полезно для пуш-уведомлений и реал-тайм обновлений данных.
8. Обработка ошибок и retry логика
async function fetchWithRetry(url, options = {}, maxRetries = 3) {
const { retries = maxRetries, ...fetchOptions } = options;
try {
const response = await fetch(url, fetchOptions);
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
return await response.json();
} catch (error) {
if (retries > 0 && (error.message.includes("503") || error instanceof TypeError)) {
// Retry на сервер-ошибки и сетевые проблемы
await new Promise((resolve) => setTimeout(resolve, 1000));
return fetchWithRetry(url, { ...options, retries: retries - 1 }, maxRetries);
}
throw error;
}
}
Рекомендации
- REST API + Fetch — стандартный выбор для большинства проектов
- Axios — если нужна большая удобство (interceptors, timeout)
- TanStack Query — если работаешь с кешированием и синхронизацией состояния
- GraphQL — для сложных данных с множеством связей
- WebSocket/SSE — для реал-тайма
Выбор способа зависит от типа приложения, требований к реал-тайму и архитектуре бэкенда.