← Назад к вопросам
Как обычно пишешь запросы?
1.8 Middle🔥 201 комментариев
#Браузер и сетевые технологии
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Структура HTTP запросов на фронтенде
Я всегда использую централизованный подход к запросам через утилиту API сервиса. В современных React приложениях это обязательно, чтобы избежать дублирования кода и иметь единую точку управления ошибками, авторизацией и переиспользованием логики.
// lib/api.ts - центральный API сервис
const API_BASE = process.env.NEXT_PUBLIC_API_URL || 'https://api.prepbro.ru';
interface FetchOptions extends RequestInit {
params?: Record<string, any>;
token?: string;
}
export async function fetchAPI<T = any>(
path: string,
options: FetchOptions = {}
): Promise<T> {
const { params, token, ...fetchOptions } = options;
// Построение URL с параметрами
const url = new URL(`${API_BASE}${path}`);
if (params) {
Object.entries(params).forEach(([key, value]) => {
url.searchParams.append(key, String(value));
});
}
// Подготовка заголовков
const headers: HeadersInit = {
'Content-Type': 'application/json',
...fetchOptions.headers,
};
if (token) {
headers['Authorization'] = `Bearer ${token}`;
}
try {
const response = await fetch(url.toString(), {
...fetchOptions,
headers,
});
if (!response.ok) {
throw new Error(`API error: ${response.status} ${response.statusText}`);
}
return response.json();
} catch (error) {
console.error(`Fetch failed for ${path}:`, error);
throw error;
}
}
Использование в компонентах
// hooks/useQuestions.ts - кастомный хук для запросов
import { useEffect, useState } from 'react';
import { fetchAPI } from '@/lib/api';
interface Question {
id: string;
title: string;
text: string;
profession_id: string;
}
export function useQuestions(professionId: string) {
const [data, setData] = useState<Question[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<Error | null>(null);
useEffect(() => {
const fetchData = async () => {
try {
setLoading(true);
const questions = await fetchAPI<Question[]>(
'/api/v1/questions',
{
params: { profession_id: professionId },
}
);
setData(questions);
} catch (err) {
setError(err instanceof Error ? err : new Error('Unknown error'));
} finally {
setLoading(false);
}
};
fetchData();
}, [professionId]);
return { data, loading, error };
}
Правильная обработка ошибок
Очень важно правильно обрабатывать ошибки - не писать логирование на одном уровне, а потом повторять его на другом. Логика должна быть иерархичной.
// Неправильно
const response = await fetch(...);
if (!response.ok) {
console.error('Error'); // логирование
throw new Error(...);
}
// Потом в компоненте
try {
const data = await api.fetch();
} catch (e) {
console.error('Another error log'); // дублирование!
}
Правильно писать логирование в API сервисе, а в компонентах просто обрабатывать результат.
POST запросы с данными
// Пример отправки данных
await fetchAPI('/api/v1/comments', {
method: 'POST',
body: JSON.stringify({
question_id: questionId,
content: userAnswer,
}),
});
Я всегда следую REST соглашениям, использую правильные HTTP методы (GET для чтения, POST для создания, PUT/PATCH для обновления) и структурирую код для переиспользования и тестируемости.