Что такое REST API и каковы его ключевые принципы?

Ответ

REST (Representational State Transfer) — это архитектурный стиль для создания масштабируемых и надежных веб-сервисов. Он не является протоколом, а скорее набором правил и ограничений для построения взаимодействия между клиентом и сервером.

Ключевые принципы REST:

  1. Клиент-серверная архитектура: Четкое разделение между клиентом (интерфейс) и сервером (данные и логика), что позволяет им развиваться независимо.
  2. Отсутствие состояния (Stateless): Каждый запрос от клиента должен содержать всю необходимую информацию для его выполнения. Сервер не хранит состояние клиента между запросами, что упрощает масштабирование.
  3. Кешируемость: Ответы от сервера должны явно помечаться как кешируемые или некешируемые. Это позволяет клиентам и промежуточным узлам (прокси) кешировать данные для улучшения производительности.
  4. Единообразный интерфейс (Uniform Interface): Это фундаментальный принцип, который включает:
    • Идентификация ресурсов по URI: Каждый ресурс имеет уникальный идентификатор (например, /users/123).
    • Манипуляция ресурсами через представления: Клиент работает не с самим ресурсом, а с его представлением (например, в формате JSON).
    • Использование стандартных HTTP-методов: GET (получить), POST (создать), PUT (обновить/заменить), DELETE (удалить).

Пример простого REST-like API на Go с net/http:

package main

import (
    "encoding/json"
    "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: "Alice"}, {ID: 2, Name: "Bob"}}
        w.Header().Set("Content-Type", "application/json")
        json.NewEncoder(w).Encode(users)
    }
}

func main() {
    http.HandleFunc("/users", usersHandler)
    http.ListenAndServe(":8080", nil)
}

Ответ 18+ 🔞

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

Вот на чём он стоит, этот ваш РЕСТ:

  1. Клиент-сервер, блядь. Чёткое разделение, как в зоне: ты — зэк (клиент), я — администрация (сервер). Ты там в своём интерфейсе вертись, а я тут с данными и логикой сижу. Развиваемся независимо, не мешаем друг другу.
  2. Без состояния, ёбта! Это святое. Каждый твой запрос — как письмо домой: должен содержать ВСЁ, что мне нужно, чтобы его исполнить. Я не буду помнить, кто ты такой и что ты в прошлый раз просил. Как золотая рыбка, блядь. Зато масштабируется — накинь ещё серверов, и всё.
  3. Кешируемость. Ответы я тебе помечаю: вот это можно в кеш засунуть и не дергать меня по пустякам, а вот это — свежее, только из печки. Экономия трафика, скорость — красота.
  4. Единый интерфейс. Тут, сука, самое мясо.
    • Каждая сущность — свой URL. Хочешь пользователя? /users/123. Хочешь кота? /cats/Васька. Всё по полочкам, блядь.
    • Работаешь не с самой сущностью, а с её бумажкой-представлением. Обычно в JSON, реже в XML (но это уже старьё, в рот меня чих-пых).
    • Используешь родные HTTP-глаголы, как они задуманы. Не выдумывай велосипед!
      • GET — посмотреть, получить (глазами, блядь, только глазами!).
      • POST — создать, отправить новенькое.
      • PUT — обновить ВСЁ, целиком заменить, как будто старый сломался.
      • DELETE — удалить нахуй, стереть в порошок.

Вот тебе примерчик на Go, чтоб понятнее было, как это выглядит в коде:

package main

import (
    "encoding/json"
    "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: "Alice"}, {ID: 2, Name: "Bob"}}
        w.Header().Set("Content-Type", "application/json")
        json.NewEncoder(w).Encode(users)
    }
}

func main() {
    http.HandleFunc("/users", usersHandler)
    http.ListenAndServe(":8080", nil)
}

Вот и вся магия, блядь. Никакой чёрной магии, только дисциплина и здравый смысл. А то некоторые строят свои API, как попало — один endpoint на всё, GET-ом данные удаляют... Пидарасы, одним словом.