Назовите основные HTTP-методы и объясните их назначение и свойства (идемпотентность, безопасность).

Ответ

Основные HTTP-методы определяют действие, которое необходимо выполнить для указанного ресурса.

Ключевые свойства:

  • Безопасный (Safe): Метод не изменяет состояние сервера. Повторные вызовы не приводят к побочным эффектам (например, GET, HEAD).
  • Идемпотентный (Idempotent): Повторный вызов метода с теми же параметрами приводит к тому же результату, что и одиночный. Состояние сервера после первого и последующих запросов будет одинаковым (например, GET, PUT, DELETE).

Основные методы:

  • GET

    • Назначение: Запрос представления ресурса. Используется для получения данных.
    • Свойства: Безопасный, Идемпотентный.
  • POST

    • Назначение: Отправка данных на сервер для обработки. Чаще всего используется для создания нового ресурса (например, нового пользователя или заказа).
    • Свойства: Небезопасный, Неидемпотентный (два одинаковых POST-запроса создадут два одинаковых ресурса с разными ID).
  • PUT

    • Назначение: Полная замена существующего ресурса или создание нового по известному URI.
    • Свойства: Небезопасный, Идемпотентный (повторный PUT с теми же данными просто перезапишет ресурс тем же самым).
  • PATCH

    • Назначение: Частичное изменение ресурса. В теле запроса передаются только изменяемые поля.
    • Свойства: Небезопасный, Неидемпотентный (в общем случае, т.к. PATCH /users/1 { op: "increment", field: "age" } при повторном вызове изменит состояние).
  • DELETE

    • Назначение: Удаление указанного ресурса.
    • Свойства: Небезопасный, Идемпотентный (повторное удаление уже удаленного ресурса вернет 404 Not Found, но состояние сервера не изменится).
  • HEAD

    • Назначение: Аналогичен GET, но сервер возвращает только заголовки, без тела ответа. Используется для проверки метаданных ресурса (дата изменения, размер) без скачивания всего содержимого.
    • Свойства: Безопасный, Идемпотентный.
  • OPTIONS

    • Назначение: Запрос информации о доступных опциях для ресурса, например, какие HTTP-методы он поддерживает (заголовок Allow).
    • Свойства: Безопасный, Идемпотентный.
// Пример создания POST-запроса в Go для отправки JSON
package main

import (
    "bytes"
    "fmt"
    "io/ioutil"
    "net/http"
)

func main() {
    // Данные, которые мы хотим отправить
    jsonData := []byte(`{"name": "Gopher", "job": "Mascot"}`)

    // Создаем новый запрос с методом POST
    req, err := http.NewRequest("POST", "https://httpbin.org/post", bytes.NewBuffer(jsonData))
    if err != nil {
        panic(err)
    }

    // Устанавливаем заголовок, чтобы сервер знал, что мы отправляем JSON
    req.Header.Set("Content-Type", "application/json")

    // Выполняем запрос
    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()

    // Читаем и выводим ответ
    body, _ := ioutil.ReadAll(resp.Body)
    fmt.Println("Response Status:", resp.Status)
    fmt.Println("Response Body:", string(body))
}

Ответ 18+ 🔞

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

Вот представь: у тебя есть сервер — это такой, блядь, склад, а ресурс — это ящик на этом складе. Метод — это твоя команда грузчику, что с этим ящиком делать. И у каждой команды есть свои, сука, свойства, которые надо знать, чтобы не вышло пиздеца.

Свойства, которые всех ебут:

  • Безопасный (Safe): Это когда ты пришёл, посмотрел на ящик и ушёл. Ящик на месте, склад не изменился. Ничего не сломал, не уронил. Как GET — пришёл, данные посмотрел и свалил.
  • Идемпотентный (Idempotent): А это, блядь, волшебное слово! Означает, что сколько раз ты ни кричи грузчику одну и ту же команду — результат будет одинаковый. Один раз сказал — ящик переставили. Десять раз орал то же самое — ящик стоит там же, куда его в первый раз поставили. Состояние склада не меняется от твоего ора. Это как PUT или DELETE.

Ну и сами команды, ёпта:

  • GET

    • Чё делает: "Эй, грузчик! Покажи-ка мне, что в том ящике лежит!" Только для получения инфы.
    • Какой: Безопасный, Идемпотентный. Можно хоть сто раз спрашивать — ящик цел, данные те же.
  • POST

    • Чё делает: "На, братан, вот тебе новая хуйня в коробке. Придумай, куда её засунуть, и дай ей номер!" Основное — создание нового.
    • Какой: Опасно, ёпта! Небезопасный и НЕидемпотентный. Крикнул два раза "создай!" — получишь две одинаковые коробки с разными номерами. Пиздец, а не склад.
  • PUT

    • Чё делает: "Видишь ящик №5? Выкинь оттуда всё старое и положи вот это! Если ящика №5 нет — создай его и положи это." Полная замена или создание по известному адресу.
    • Какой: Небезопасный (меняет склад), но Идемпотентный! Орал "замени в №5 на это!" один раз или десять — в ящике №5 будет одно и то же. Никаких дублей.
  • PATCH

    • Чё делает: "В ящике №5 есть поле 'цвет'. Сделай его 'красным'." Не всю коробку меняет, а только кусочек.
    • Какой: Небезопасный и, внимание, в общем случае НЕидемпотентный! Потому что если команда была "увеличить счётчик на 1", то каждый новый крик будет менять состояние. Хуйня, а не команда, если неаккуратно.
  • DELETE

    • Чё делает: "Ящик №5 — нахуй в мусорку!"
    • Какой: Небезопасный, но Идемпотентный! Удалил ящик — его нет. Кричишь "удали ящик №5" ещё раз — он уже удалён, состояние склада не меняется. Просто во второй раз грузчик скажет "чё, бля, его уже нет".
  • HEAD

    • Чё делает: "Эй, грузчик! Не открывая ящик №5, скажи, он большой? И когда его последний раз трогали?" Только заголовки, без самого содержимого.
    • Какой: Безопасный, Идемпотентный. Просто справка.
  • OPTIONS

    • Чё делает: "А что вообще можно делать с ящиком №5? Можно его смотреть, менять, удалять?" Запрос возможностей.
    • Какой: Безопасный, Идемпотентный. Просто узнал правила и пошёл дальше.
// Вот, смотри, как на Go нахуярить POST-запрос, чтобы что-то создать
package main

import (
    "bytes"
    "fmt"
    "io/ioutil"
    "net/http"
)

func main() {
    // Данные, которые мы хотим отправить
    jsonData := []byte(`{"name": "Gopher", "job": "Mascot"}`)

    // Создаем новый запрос с методом POST
    req, err := http.NewRequest("POST", "https://httpbin.org/post", bytes.NewBuffer(jsonData))
    if err != nil {
        panic(err)
    }

    // Устанавливаем заголовок, чтобы сервер знал, что мы отправляем JSON
    req.Header.Set("Content-Type", "application/json")

    // Выполняем запрос
    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()

    // Читаем и выводим ответ
    body, _ := ioutil.ReadAll(resp.Body)
    fmt.Println("Response Status:", resp.Status)
    fmt.Println("Response Body:", string(body))
}

Вот и вся магия, блядь. Главное — запомни, где можно орать много раз без последствий (идемпотентность), а где один крик — и понеслась пизда по кочкам.