Как frontend и backend взаимодействуют между собой?

Ответ

Frontend (клиентская часть, например, браузер или мобильное приложение) и Backend (серверная часть) взаимодействуют по сети, обмениваясь данными через API (Application Programming Interface).

Основные способы взаимодействия:

  1. REST API (Representational State Transfer)

    • Принцип: Самый популярный подход. Взаимодействие строится вокруг ресурсов (например, /users, /products) с использованием стандартных методов HTTP:
      • GET: получение данных.
      • POST: создание новых данных.
      • PUT/PATCH: обновление данных.
      • DELETE: удаление данных.
    • Формат данных: Чаще всего используется JSON.
    • Пример: Frontend запрашивает список пользователей, отправив GET-запрос на http://api.example.com/users. Backend обрабатывает запрос, извлекает данные из базы данных и возвращает их в виде JSON-массива.
  2. GraphQL

    • Принцип: Более гибкая альтернатива REST. Frontend отправляет один запрос, в котором точно указывает, какие поля и связанные данные ему нужны. Это решает проблему избыточной (over-fetching) или недостаточной (under-fetching) выборки данных.
    • Пример: Вместо нескольких REST-запросов для получения пользователя и его заказов, Frontend делает один GraphQL-запрос, где сразу просит user с полем name и вложенным списком orders с полями id и status.
  3. WebSockets

    • Принцип: Устанавливает постоянное двустороннее соединение между клиентом и сервером. Идеально подходит для приложений реального времени.
    • Применение: Чаты, онлайн-игры, биржевые котировки, живые уведомления.
  4. gRPC (Google Remote Procedure Call)

    • Принцип: Высокопроизводительная система для вызова удаленных процедур. Использует Protocol Buffers для сериализации данных, что эффективнее JSON. Работает поверх HTTP/2.
    • Применение: В основном для связи между микросервисами внутри системы, где важна скорость и низкая задержка.

Пример простого REST API на Go:

// main.go
package main

import (
    "encoding/json"
    "log"
    "net/http"
)

type User struct {
    ID   int    `json:"id"`
    Name string `json:"name"`
}

func usersHandler(w http.ResponseWriter, r *http.Request) {
    if r.Method == http.MethodGet {
        users := []User{{ID: 1, Name: "John Doe"}, {ID: 2, Name: "Jane Doe"}}
        w.Header().Set("Content-Type", "application/json")
        if err := json.NewEncoder(w).Encode(users); err != nil {
            http.Error(w, "Failed to encode users", http.StatusInternalServerError)
        }
    }
}

func main() {
    http.HandleFunc("/api/users", usersHandler)
    log.Println("Server is running on :8080")
    if err := http.ListenAndServe(":8080", nil); err != nil {
        log.Fatal(err)
    }
}

Для безопасности этого взаимодействия используются CORS (для контроля доступа из разных источников), JWT-токены (для аутентификации и авторизации) и обязательная валидация всех входящих данных на стороне бэкенда.

Ответ 18+ 🔞

А, ну ты про то, как эта фронтенд-штука с бэкендом разговаривает? Да это ж, блядь, целый цирк с конями, ёпта! Сидит у тебя в браузере эта мартышлюшка-интерфейс и думает, как бы до сервака достучаться, чтобы данные выпросить или отправить. А там, на том конце, здоровенный сервер, как Герасим из рассказа, молчит, но силушки у него — овердохуища!

Ну, основные способы, как они друг друга ебут, то есть, общаются:

  1. REST API (Эти ваши репрезентативные трансферы состояния)

    • Суть: Самый распиздяйски популярный метод. Там всё вокруг «ресурсов» вертится, типа /users или /products. Используют стандартные HTTP-команды, как дирижёр палочкой:
      • GET: «Дай-ка сюда!» (получить данные).
      • POST: «На, создай!» (создать новое).
      • PUT/PATCH: «Исправь, падла!» (обновить).
      • DELETE: «Удали нахуй!» (ну, ты понял).
    • На каком языке: Обычно на JSON, это как они друг другу записки передают.
    • Пример из жизни: Фронтенд орёт: «Эй, сервак, дай список пользователей!» (GET запрос на http://api.example.com/users). Бэкенд, такой: «Ща, сука, из базы вытащу...», и шлёт назад JSON-массив. Всё просто, как три копейки.
  2. GraphQL

    • Суть: А это уже для хитрожопых. Фронтенд не орёт кучу мелких запросов, а делает один, но такой подробный, что там расписано до каждой запятой, что ему надо. Решает проблему, когда сервер либо хуйню ненужную присылает (over-fetching), либо, наоборот, нихуя не досылает (under-fetching).
    • Пример: Вместо того чтобы сначала просить user, а потом отдельно его orders, фронтенд одним махом: «Дай user { name, orders { id, status } }». И сервер, скрипя зубами, но делает.
  3. WebSockets

    • Суть: Это когда они не просто перекидываются записками, а пробивают тоннель и держат его открытым. Постоянная двусторонняя связь, ебать мои старые костыли!
    • Где нужно: Все эти ваши чаты, где сообщения летят мгновенно, онлайн-игры или биржевые графики, которые пляшут. Типа, «я тебе — ты мне», без остановки.
  4. gRPC (Этот, гугловский вызов процедур)

    • Суть: Для максималистов, которым JSON — говно собачье, и нужна скорость, как у пули. Использует Protocol Buffers — данные упаковывает так компактно, что аж жуть. Работает поверх HTTP/2.
    • Где юзают: Чаще внутри ихних микросервисных джунглей, где один сервис другому быстро-быстро на ушко что-то шепчет. Для простых веб-приложений — это как из пушки по воробьям, но там, где надо, — пиздец как эффективно.

Вот, смотри, как на Go этот самый REST, простейший, выглядит. Код не трогаю, он святой:

// main.go
package main

import (
    "encoding/json"
    "log"
    "net/http"
)

type User struct {
    ID   int    `json:"id"`
    Name string `json:"name"`
}

func usersHandler(w http.ResponseWriter, r *http.Request) {
    if r.Method == http.MethodGet {
        users := []User{{ID: 1, Name: "John Doe"}, {ID: 2, Name: "Jane Doe"}}
        w.Header().Set("Content-Type", "application/json")
        if err := json.NewEncoder(w).Encode(users); err != nil {
            http.Error(w, "Failed to encode users", http.StatusInternalServerError)
        }
    }
}

func main() {
    http.HandleFunc("/api/users", usersHandler)
    log.Println("Server is running on :8080")
    if err := http.ListenAndServe(":8080", nil); err != nil {
        log.Fatal(err)
    }
}

А и ещё, чувак, самое главное — безопасность, ёклмн! А то придёт какой-нибудь пидарас шерстяной и начнёт тебе в API гадить.

  • CORS — это чтоб с левых сайтов к твоему серверу не лезли.
  • JWT-токены — как пропуск в закрытый клуб: предъявил — иди, нет — иди на хуй.
  • Валидация на бэкенде — это святое! Доверия к данным с фронта — ноль, ебать. Проверяй всё, как будто тебя хотят обоссать. Иначе — пиши пропало.

Вот так вот, в двух словах. А если подробнее — это, блядь, на целую книгу, в рот меня чих-пых!