Приведи примеры задач, где соединял Frontend и Backend
Комментарии (2)
Ответ сгенерирован нейросетью и может содержать ошибки
Примеры интеграции Frontend и Backend в моей практике
В ходе разработки веб-приложений я регулярно сталкивался с задачами, требующими тесной интеграции между фронтендом и бэкендом. Вот несколько характерных примеров из реальных проектов.
1. Система онлайн-бронирования для сервиса аренды автомобилей
Задача: Реализовать динамический интерфейс выбора дат, отображения доступных автомобилей в реальном времени и моментального расчета стоимости.
Frontend (React + Redux Toolkit + React Query):
- Календарь с выбором дат (библиотека
react-datepicker) - Карточки автомобилей с фильтрами (тип коробки передач, класс авто)
- Интерактивный калькулятор стоимости, пересчитывающий сумму при изменении параметров
Backend (Node.js + Express + MongoDB):
- REST API эндпоинты
/api/cars/available,/api/booking/calculate - Валидация дат и проверка доступности автомобилей
- Расчет стоимости с учетом динамических тарифов и скидок
Интеграция:
// Frontend: запрос доступных автомобилей
const { data: availableCars, isLoading } = useQuery({
queryKey: ['availableCars', filters],
queryFn: () => axios.get('/api/cars/available', { params: filters })
.then(res => res.data),
staleTime: 30000 // Кэшируем на 30 секунд
});
// Backend: обработка запроса
router.get('/available', async (req, res) => {
const { startDate, endDate, transmission } = req.query;
// Проверяем конфликты бронирований
const bookedCars = await Booking.find({
$or: [
{ startDate: { $lte: endDate }, endDate: { $gte: startDate } }
]
}).distinct('carId');
// Ищем доступные автомобили
const availableCars = await Car.find({
_id: { $nin: bookedCars },
transmission: transmission || { $exists: true }
}).populate('model');
res.json(availableCars);
});
2. Административная панель с реальными уведомлениями
Задача: Создать дашборд для менеджеров с отображением новых заказов в реальном времени и возможностью мгновенного изменения статусов.
Frontend (Vue 3 + Pinia + Socket.io-client):
- Список заказов с цветовой индикацией статусов
- Модальные окна для редактирования заказов
- Система уведомлений о новых заказах (WebSocket)
Backend (Python Django + Django REST Framework + Redis):
- REST API для CRUD операций с заказами
- Каналы Django для WebSocket соединений
- Redis как брокер сообщений для реального времени
Интеграция:
# Backend: WebSocket потребитель для уведомлений
class OrderConsumer(AsyncWebsocketConsumer):
async def connect(self):
self.room_group_name = 'admin_orders'
await self.channel_layer.group_add(
self.room_group_name,
self.channel_name
)
await self.accept()
async def new_order(self, event):
await self.send(text_data=json.dumps({
'type': 'new_order',
'order': event['order'],
'message': 'Поступил новый заказ'
}))
# Frontend: обработка WebSocket сообщений
const socket = io('https://api.example.com');
const orderStore = useOrderStore();
socket.on('new_order', (data) => {
orderStore.addOrder(data.order);
showNotification(data.message);
});
// Обновление статуса заказа
const updateOrderStatus = async (orderId, status) => {
const response = await axios.patch(
`/api/orders/${orderId}/`,
{ status }
);
socket.emit('order_updated', response.data);
};
3. Загрузка и обработка файлов с прогресс-баром
Задача: Реализовать загрузку больших CSV-файлов (до 500МБ) с отображением прогресса и последующей асинхронной обработкой.
Frontend (React + Axios):
- Drag-and-drop интерфейс для загрузки файлов
- Прогресс-бар с процентами загрузки
- Таблица с предпросмотром загруженных данных
- Система опроса статуса обработки файла
Backend (Node.js + Multer + Bull Queue):
- Мультипартная загрузка файлов с chunk'ами
- Очередь задач для обработки CSV в фоновом режиме
- Webhook или polling эндпоинт для проверки статуса
Интеграция:
// Frontend: загрузка с отслеживанием прогресса
const uploadFile = async (file) => {
const formData = new FormData();
formData.append('csvFile', file);
const response = await axios.post('/api/upload', formData, {
headers: { 'Content-Type': 'multipart/form-data' },
onUploadProgress: (progressEvent) => {
const percent = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
);
setUploadProgress(percent);
}
});
// Начинаем опрос статуса обработки
const jobId = response.data.jobId;
pollProcessingStatus(jobId);
};
// Backend: обработка загрузки и постановка в очередь
router.post('/upload', upload.single('csvFile'), async (req, res) => {
const job = await processingQueue.add({
filePath: req.file.path,
userId: req.user.id
});
res.json({
jobId: job.id,
message: 'Файл принят в обработку'
});
});
// Эндпоинт для проверки статуса
router.get('/processing-status/:jobId', async (req, res) => {
const job = await processingQueue.getJob(req.params.jobId);
res.json({
status: await job.getState(),
progress: job.progress(),
result: job.returnvalue
});
});
4. Поиск с автодополнением и кэшированием
Задача: Создать быстрый поиск по каталогу из 100k+ товаров с автодополнением и умным кэшированием.
Frontend (React + Debounce + SWR):
- Поле ввода с debounce 300мс
- Выпадающий список с автодополнением
- Кэширование результатов поиска на клиенте
Backend (Node.js + Elasticsearch + Redis):
- Elasticsearch для полнотекстового поиска
- Redis для кэширования популярных запросов
- REST API с пагинацией и фильтрацией
Интеграция:
// Frontend: компонент поиска с debounce
const SearchComponent = () => {
const [query, setQuery] = useState('');
const debouncedQuery = useDebounce(query, 300);
const { data: suggestions } = useSWR(
debouncedQuery ? `/api/search/suggest?q=${debouncedQuery}` : null,
fetcher,
{ dedupingInterval: 5000 }
);
return (
<div>
<input
value={query}
onChange={(e) => setQuery(e.target.value)}
placeholder="Поиск товаров..."
/>
{suggestions && (
<ul>
{suggestions.map(item => (
<li key={item.id}>{item.name}</li>
))}
</ul>
)}
</div>
);
};
// Backend: обработчик поиска с двухуровневым кэшем
router.get('/suggest', async (req, res) => {
const { q } = req.query;
const cacheKey = `suggest:${q}`;
// Проверяем Redis кэш
const cached = await redis.get(cacheKey);
if (cached) {
return res.json(JSON.parse(cached));
}
// Ищем в Elasticsearch
const result = await elasticsearch.search({
index: 'products',
body: {
query: {
multi_match: {
query: q,
fields: ['name^3', 'description', 'category']
}
},
size: 10
}
});
const suggestions = result.hits.hits.map(hit => hit._source);
// Кэшируем на 1 час
await redis.setex(cacheKey, 3600, JSON.stringify(suggestions));
res.json(suggestions);
});
Ключевые принципы интеграции, которых я придерживаюсь:
- Единая система валидации - синхронизация правил валидации на фронтенде (для UX) и бэкенде (для безопасности)
- Согласованные контракты API - использование TypeScript interfaces на фронтенде и соответствующих DTO на бэкенде
- Грамотная обработка ошибок - унифицированные форматы ошибок с понятными кодами и сообщениями
- Оптимистичные обновления - улучшение UX через мгновенное отражение изменений с последующей синхронизацией
- Мониторинг и логирование - сквозная идентификация запросов через requestId для упрощения отладки
Эти примеры демонстрируют, что успешная интеграция фронтенда и бэкенда требует не только технических навыков, но и глубокого понимания бизнес-логики, внимания к UX и продуманной архитектуры взаимодействия между клиентом и сервером.