Что такое POST-запрос и когда его следует использовать?

Ответ

POST — это один из основных методов HTTP, предназначенный для отправки данных на сервер с целью создания нового ресурса или выполнения операции, которая изменяет состояние сервера.

Ключевые характеристики:

  • Данные в теле: В отличие от GET, данные передаются в теле (body) запроса, а не в URL. Это позволяет отправлять большие объемы данных и скрывать их от логов сервера и истории браузера.
  • Неидемпотентность: POST не является идемпотентным. Это означает, что повторная отправка одного и того же запроса может привести к созданию нескольких одинаковых ресурсов (например, двух одинаковых пользователей).
  • Изменение состояния: POST всегда предполагает, что на сервере произойдет какое-то изменение: создание записи в базе данных, отправка сообщения и т.д.

Когда использовать POST?

  • Для создания дочернего ресурса: POST /users для создания нового пользователя.
  • Для отправки данных веб-форм.
  • Для выполнения операций, у которых нет четкого аналога в REST (например, POST /users/123/send-password-reset).
  • Когда нужно передать чувствительные данные (логин, пароль).

Пример на Go

1. Клиент: отправка POST-запроса

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

func main() {
    userData := map[string]string{"name": "Alice", "email": "alice@example.com"}
    jsonData, _ := json.Marshal(userData)

    resp, err := http.Post(
        "https://api.example.com/users",
        "application/json",
        bytes.NewBuffer(jsonData),
    )
    if err != nil {
        log.Fatal(err)
    }
    defer resp.Body.Close()

    log.Println("Статус ответа:", resp.Status)
}

2. Сервер: обработка POST-запроса

// User - структура для декодирования JSON
type User struct {
    Name  string `json:"name"`
    Email string `json:"email"`
}

func createUserHandler(w http.ResponseWriter, r *http.Request) {
    if r.Method != http.MethodPost {
        http.Error(w, "Метод не разрешен", http.StatusMethodNotAllowed)
        return
    }

    var u User
    if err := json.NewDecoder(r.Body).Decode(&u); err != nil {
        http.Error(w, "Некорректный JSON", http.StatusBadRequest)
        return
    }

    // ... Логика создания пользователя в БД ...
    log.Printf("Создан пользователь: Имя=%s, Email=%s", u.Name, u.Email)

    w.WriteHeader(http.StatusCreated) // 201 Created - правильный статус для создания
    fmt.Fprintf(w, "Пользователь %s создан", u.Name)
}