Средний

Как фронтенд общается с бэкендом

Урок 5 из 5 в курсе Основы фронтенда для бэкенд-разработчика

Содержание курса (5/5)

Как фронтенд общается с бэкендом

REST API, JSON, WebSocket, Server-Sent Events — способы обмена данными между браузером и сервером. Этот урок собирает всё воедино и показывает полный цикл запрос-ответ с точки зрения обеих сторон.

Почему это важно: Это ядро вашей работы: каждый endpoint, который вы пишете, вызывается фронтендом. Понимание полного цикла — от кнопки в браузере до ответа сервера — помогает проектировать удобные API и быстро находить баги на стыке.

Главная идея

Фронтенд и бэкенд общаются по протоколу HTTP (запрос → ответ). Для real-time используются WebSocket и SSE. Формат данных — чаще всего JSON. Каждая сторона отвечает за свою часть контракта.

Как это выглядит на практике

  1. Фронтенд-разработчик читает документацию API (endpoint, метод, формат тела)
  2. JS-код формирует запрос: URL, заголовки, тело (JSON или FormData)
  3. Браузер отправляет HTTP-запрос, добавляя Cookie и CORS-заголовки
  4. Сервер маршрутизирует запрос к нужному контроллеру
  5. Контроллер валидирует данные, выполняет бизнес-логику, формирует ответ
  6. Сервер отправляет HTTP-ответ со статус-кодом, заголовками и телом (JSON/HTML)
  7. JS обрабатывает ответ: обновляет UI при успехе или показывает ошибку

Примеры кода

Полный CRUD-цикл на фронтенде

// CREATE — POST /api/tasks
async function createTask(title) {
  const res = await fetch('/api/tasks', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ task: { title } })
  });
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
  return res.json(); // { id: 1, title: '...', created_at: '...' }
}

// READ — GET /api/tasks
async function getTasks() {
  const res = await fetch('/api/tasks');
  return res.json(); // [{ id: 1, title: '...' }, ...]
}

// UPDATE — PATCH /api/tasks/1
async function updateTask(id, title) {
  const res = await fetch(`/api/tasks/${id}`, {
    method: 'PATCH',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ task: { title } })
  });
  return res.json();
}

// DELETE — DELETE /api/tasks/1
async function deleteTask(id) {
  await fetch(`/api/tasks/${id}`, { method: 'DELETE' });
}

Соответствующий контроллер на бэкенде (Rails)

class Api::TasksController < ApplicationController
  # GET /api/tasks
  def index
    tasks = Task.order(created_at: :desc)
    render json: tasks
  end

  # POST /api/tasks
  def create
    task = Task.new(task_params)
    if task.save
      render json: task, status: :created
    else
      render json: { errors: task.errors.full_messages },
             status: :unprocessable_entity
    end
  end

  private

  def task_params
    params.require(:task).permit(:title)
  end
end

Что происходит под капотом

  • Content-Type: application/json говорит серверу, что тело — JSON, а не form-data
  • Статус-коды: 2xx — успех, 4xx — ошибка клиента, 5xx — ошибка сервера
  • CSRF-токен обязателен для мутирующих запросов (POST/PATCH/DELETE) в серверных фреймворках
  • WebSocket — постоянное соединение для двусторонней real-time коммуникации (чаты, уведомления)
  • SSE (Server-Sent Events) — односторонний поток данных от сервера к клиенту (ленты обновлений)

Типичные ошибки и заблуждения

  • «JSON — единственный формат API» — HTML-фрагменты (Turbo/HTMX), XML, Protocol Buffers тоже используются
  • «REST — это стандарт» — REST — набор архитектурных принципов, а не строгая спецификация
  • «WebSocket нужен всегда для real-time» — часто достаточно SSE или даже поллинга

Ключевые выводы

  • HTTP запрос = метод + URL + заголовки + тело; ответ = статус + заголовки + тело
  • JSON — основной формат обмена данными между фронтом и бэкендом
  • Контракт API (URL, метод, формат данных, коды ответов) должен быть документирован

Термины урока

{:term=>"WebSocket", :definition=>"Протокол для двусторонней real-time связи между клиентом и сервером через постоянное соединение"}
{:term=>"SSE", :definition=>"Server-Sent Events — механизм для push-уведомлений от сервера к клиенту через HTTP"}
{:term=>"CSRF-токен", :definition=>"Уникальный токен для защиты от подделки межсайтовых запросов, встраивается в формы и заголовки"}

Связь с работой backend-разработчика

Каждый endpoint — это контракт между фронтом и бэком. Чёткие статус-коды, консистентный формат ответов и документация — основа продуктивного взаимодействия. Проектируйте API так, чтобы фронтенду было удобно его вызывать.

Мини-разбор реальной ситуации

Фронтенд-разработчик жаловался, что при ошибке валидации API возвращает 200 OK с полем error в JSON. Из-за этого обработка ошибок на фронте превращалась в парсинг тела вместо проверки статус-кода. После рефакторинга бэкенд стал возвращать 422 Unprocessable Entity с массивом ошибок — код фронтенда стал чище и надёжнее.

Что запомнить

  • HTTP-запрос = метод + URL + заголовки + тело (JSON или FormData)
  • Используйте правильные статус-коды: 201 Created, 422 для ошибок валидации, 404 Not Found
  • Документируйте контракт API — это экономит время обеим командам

Итог

Фронтенд и бэкенд общаются через HTTP. JSON — lingua franca этого общения. Чёткие контракты, правильные статус-коды и понимание полного цикла запрос-ответ — ключ к эффективной разработке на стыке.

Комментарии к уроку

Войдите, чтобы оставить комментарий.

Пока нет комментариев — будьте первым.