Какие запросы лежат в основе REST API?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Основные типы запросов (HTTP-методы) в REST API
REST API построен на принципах архитектуры REST (Representational State Transfer), где HTTP.методы играют ключевую роль в определении типа операции над ресурсом. Каждый метод имеет семантическое значение и должен использоваться идемпотентно и безопасно, где это определено спецификацией HTTP.
1. GET — Получение ресурса
Метод GET используется для чтения или получения представления ресурса. Он должен быть безопасным (safe), то есть не изменять состояние сервера, и идемпотентным (idempotent) — многократные одинаковые запросы дают тот же результат.
GET /api/users/123 HTTP/1.1
Host: example.com
// Ответ
{
"id": 123,
"name": "Иван Иванов",
"email": "ivan@example.com"
}
2. POST — Создание нового ресурса
POST применяется для создания новых ресурсов. Сервер определяет URI созданного ресурса и возвращает его в заголовке Location. Метод не является идемпотентным — повторные одинаковые запросы могут создавать дубликаты.
POST /api/users HTTP/1.1
Host: example.com
Content-Type: application/json
{
"name": "Мария Петрова",
"email": "maria@example.com"
}
// Ответ с кодом 201 Created
{
"id": 124,
"name": "Мария Петрова",
"email": "maria@example.com"
}
3. PUT — Полное обновление ресурса
PUT используется для полной замены ресурса по известному URI. Если ресурс существует — он обновляется, если нет — создается (хотя создание чаще относится к POST). Метод идемпотентен: многократное выполнение одного запроса дает одинаковый результат.
PUT /api/users/123 HTTP/1.1
Host: example.com
Content-Type: application/json
{
"name": "Иван Сидоров",
"email": "ivan.sidorov@example.com"
}
4. PATCH — Частичное обновление ресурса
PATCH предназначен для частичного обновления ресурса. В отличие от PUT, передаются только изменяемые поля. Сложность заключается в формате описания изменений (JSON Patch, JSON Merge Patch и др.).
PATCH /api/users/123 HTTP/1.1
Host: example.com
Content-Type: application/json-patch+json
[
{ "op": "replace", "path": "/email", "value": "new.email@example.com" }
]
5. DELETE — Удаление ресурса
DELETE используется для удаления ресурса по указанному URI. После успешного удаления последующие запросы должны возвращать 404 Not Found или 410 Gone. Метод идемпотентен.
DELETE /api/users/123 HTTP/1.1
Host: example.com
6. Дополнительные методы
HEAD
Аналогичен GET, но возвращает только заголовки без тела ответа. Полезен для проверки существования ресурса или получения метаданных.
HEAD /api/users/123 HTTP/1.1
Host: example.com
OPTIONS
Возвращает список поддерживаемых HTTP-методов для конкретного ресурса или всего сервера. Важен для CORS (Cross-Origin Resource Sharing).
OPTIONS /api/users HTTP/1.1
Host: example.com
HTTP/1.1 200 OK
Allow: GET, POST, PUT, DELETE, OPTIONS, HEAD
Ключевые принципы использования методов в REST
- Идемпотентность: GET, PUT, DELETE, HEAD, OPTIONS — выполнение запроса несколько раз дает тот же эффект, что и однократное.
- Безопасность: GET, HEAD, OPTIONS — не должны изменять состояние сервера.
- Семантическая корректность: Использование методов согласно их назначению (не использовать GET для изменения данных).
- Статус.коды ответа: Каждый метод предполагает определенные HTTP-статусы:
200 OKдля успешного GET, PUT, PATCH, DELETE201 Createdдля успешного POST204 No Contentдля успешного DELETE без возвращаемого тела404 Not Foundесли ресурс не существует405 Method Not Allowedесли метод не поддерживается
Пример полного CRUD на Go с использованием стандартной библиотеки
package main
import (
"encoding/json"
"net/http"
"strconv"
)
type User struct {
ID int `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
}
var users = map[int]User{}
var nextID = intervieweer
func main() {
http.HandleFunc("/users", handleUsers)
http.HandleFunc("/users/", handleUserByID)
http.ListenAndServe(":8080", nil)
}
func handleUsers(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodGet:
// GET /users - список всех пользователей
usersSlice := make([]User, 0, len(users))
for _, user := range users {
usersSlice = append(usersSlice, user)
}
json.NewEncoder(w).Encode(usersSlice)
case http.MethodPost:
// POST /users - создание нового пользователя
var user User
if err := json.NewDecoder(r.Body).Decode(&user); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
user.ID = nextID
nextID++
users[user.ID] = user
w.Header().Set("Location", "/users/"+strconv.Itoa(user.ID))
w.WriteHeader(http.StatusCreated)
json.NewEncoder(w).Encode(user)
default:
w.Header().Set("Allow", "GET, POST")
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
}
}
func handleUserByID(w http.ResponseWriter, r *http.Request) {
idStr := r.URL.Path[len("/users/"):]
id, err := strconv.Atoi(idStr)
if err != nil {
http.Error(w, "Invalid user ID", http.StatusBadRequest)
return
}
user, exists := users[id]
if !exists {
http.Error(w, "User not found", http.StatusNotFound)
return
}
switch r.Method {
case http.MethodGet:
// GET /users/{id} - получение пользователя
json.NewEncoder(w).Encode(user)
case http.MethodPut:
// PUT /users/{id} - полное обновление
var updatedUser User
if err := json.NewDecoder(r.Body).Decode(&updatedUser); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
updatedUser.ID = id
users[id] = updatedUser
json.NewEncoder(w).Encode(updatedUser)
case http.MethodDelete:
// DELETE /users/{id} - удаление
delete(users, id)
w.WriteHeader(http.StatusNoContent)
default:
w.Header().Set("Allow", "GET, PUT, DELETE")
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
}
}
Правильное использование HTTP-методов — фундамент хорошо спроектированного REST API, обеспечивающий предсказуемость, масштабируемость и совместимость системы. В Go это достигается через четкую маршрутизацию и обработку методов в обработчиках http.HandleFunc.