Які основні HTTP методи використовуються в REST
В архітектурному стилі REST методи зіставляються з CRUD-операціями над даними:
🟢 Junior Level
HTTP-методи (HTTP Verbs / дієслова HTTP) — це стандартні команди протоколу HTTP (специфікація RFC 9110), які повідомляють серверу, яку дію клієнт хоче виконати над зазначеним ресурсом (URI).
В архітектурному стилі REST методи зіставляються з CRUD-операціями над даними:
| HTTP Метод | CRUD-операція | Призначення | Приклад URI | Успішний статус-код |
|---|---|---|---|---|
GET |
Read | Отримання представлення ресурсу (читання) | GET /api/v1/orders/42 |
200 OK |
POST |
Create | Створення нового дочірнього ресурсу або виклик дії | POST /api/v1/orders |
201 Created |
PUT |
Update (Replace) | Повна заміна ресурсу за вказаною адресою | PUT /api/v1/orders/42 |
200 OK / 204 No Content |
PATCH |
Update (Partial) | Часткове оновлення окремих полів ресурсу | PATCH /api/v1/orders/42 |
200 OK / 204 No Content |
DELETE |
Delete | Видалення зазначеного ресурсу | DELETE /api/v1/orders/42 |
204 No Content |
Приклад реалізації REST-контролера на Spring Boot 3
package com.example.controller;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import java.net.URI;
import java.util.List;
@RestController
@RequestMapping("/api/v1/products")
public class ProductController {
private final ProductService productService;
public ProductController(ProductService productService) {
this.productService = productService;
}
// 1. GET: читання списку або одного елемента
@GetMapping("/{id}")
public ResponseEntity<ProductDto> getProduct(@PathVariable Long id) {
return ResponseEntity.ok(productService.findById(id));
}
// 2. POST: створення ресурсу із заголовком Location
@PostMapping
public ResponseEntity<ProductDto> createProduct(@RequestBody CreateProductRequest req) {
ProductDto created = productService.create(req);
URI location = ServletUriComponentsBuilder.fromCurrentRequest()
.path("/{id}")
.buildAndExpand(created.id())
.toUri();
return ResponseEntity.created(location).body(created); // 201 Created + Location
}
// 3. PUT: повна заміна ресурсу
@PutMapping("/{id}")
public ResponseEntity<ProductDto> replaceProduct(@PathVariable Long id,
@RequestBody ReplaceProductRequest req) {
return ResponseEntity.ok(productService.replace(id, req));
}
// 4. PATCH: часткове оновлення
@PatchMapping("/{id}")
public ResponseEntity<ProductDto> patchProduct(@PathVariable Long id,
@RequestBody PatchProductRequest req) {
return ResponseEntity.ok(productService.patch(id, req));
}
// 5. DELETE: видалення ресурсу
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteProduct(@PathVariable Long id) {
productService.delete(id);
return ResponseEntity.noContent().build(); // 204 No Content
}
}
🟡 Middle Level
Класифікація методів: Безпечність (Safe) та Ідемпотентність (Idempotent)
За специфікацією RFC 9110 (HTTP Semantics) усі методи поділяються за двома фундаментальними характеристиками:
┌─── Safe (Безпечний: не змінює стан на сервері): GET, HEAD, OPTIONS, TRACE
┌─── Властивості ┤
│ └─── Idempotent (Ідемпотентний: повтор N разів дає той самий результат): GET, HEAD, PUT, DELETE, OPTIONS
HTTP Методи ┤
│ ┌─── PUT: Повна заміна (усі поля обов'язкові)
└─── Мутації ┼─── PATCH: Часткове оновлення (RFC 6902 / RFC 7386)
└─── POST: Створення / Запуск бізнес-операції (НЕ ідемпотентний!)
Зведена матриця властивостей методів
| Метод | Наявність тіла запиту | Безпечний (Safe)? | Ідемпотентний (Idempotent)? | Кешований (Cacheable)? |
|---|---|---|---|---|
GET |
❌ Ні | ✅ Так | ✅ Так | ✅ Так (за замовчуванням) |
HEAD |
❌ Ні | ✅ Так | ✅ Так | ✅ Так |
OPTIONS |
❌ Ні | ✅ Так | ✅ Так | ❌ Ні |
POST |
✅ Так | ❌ Ні | ❌ Ні | ⚠️ Лише з явним Cache-Control |
PUT |
✅ Так | ❌ Ні | ✅ Так | ❌ Ні |
PATCH |
✅ Так | ❌ Ні | ⚠️ Залежить від операції | ❌ Ні |
DELETE |
⚠️ Не рекомендовано | ❌ Ні | ✅ Так | ❌ Ні |
Допоміжні методи: HEAD та OPTIONS
HEAD: виконує абсолютно такий самий запит, якGET, але сервер повертає тільки HTTP-заголовки без тіла відповіді. Застосування: перевірка розміру великого файлу (Content-Length) або валідності кешу (ETag,Last-Modified) до початку реального завантаження.OPTIONS: опитування комунікаційних можливостей сервера. Застосування: механізм CORS Preflight у браузерах. Перед відправкою нестандартного запиту браузер надсилаєOPTIONS, а сервер повертає дозволені методи (Access-Control-Allow-Methods: GET, POST, PUT, DELETE) і заголовки.
🔴 Senior Level
Тонкощі семантики PUT vs PATCH
- Суворий контракт
PUT(Повна заміна):- Якщо надіслано
PUT /users/42з тілом{"name": "Ivan"}, а у користувача в БД було заповнене полеemail: "ivan@test.com", бекенд зобов’язаний затерти email вnull, оскількиPUTзаміщує ресурс повністю. Якщо поле потрібно зберегти, клієнт зобов’язаний надіслати його заново.
- Якщо надіслано
- Специфікації
PATCH:- JSON Merge Patch (RFC 7386): клієнт надсилає тільки змінювані поля:
{"email": "new@mail.com"}. Проблема: як відрізнити «поле не передано (не змінювати)» від «поле передано якnull(стерти значення)»? У Spring Boot це вирішується через модульorg.openapitools.jackson.nullable.JsonNullable<T>. - JSON Patch (RFC 6902): надсилається декларативний масив атомарних операцій (
add,remove,replace,copy,move,test):[ { "op": "replace", "path": "/email", "value": "new@mail.com" }, { "op": "remove", "path": "/phoneNumber" } ]
- JSON Merge Patch (RFC 7386): клієнт надсилає тільки змінювані поля:
Автоматичні повтори (Retries) у Service Mesh (Envoy / Istio)
У розподілених мікросервісних системах знання ідемпотентності методів є критичним при налаштуванні мережевих політик:
- Безпечні повтори (Safe Retries): При отриманні мережевої помилки (
503 Service Unavailable,Connection Reset) проксі Envoy / Sidecar може автоматично повторити запитиGET,PUT,DELETEбез ризику зіпсувати дані. - Небезпека повторів для
POST: Автоматичний повтор запитуPOSTкатегорично заборонений (ризик подвійного списання грошей з рахунку або дублювання замовлення). Для безпечного повторуPOSTв архітектуру впроваджують заголовокIdempotency-Keyзі збереженням унікальних ключів у Redis.
Тунелювання методів (X-HTTP-Method-Override)
Деякі застарілі корпоративні проксі-сервери, фаєрволи (WAF) та клієнти блокують методи PUT, PATCH або DELETE.
- Для обходу обмежень використовують тунелювання через
POSTіз заголовком:POST /api/v1/orders/42 HTTP/1.1 X-HTTP-Method-Override: DELETE - У Spring Boot підтримка тунелювання вмикається через бін
HiddenHttpMethodFilter.
4 Tricky Questions
1. У чому принципова відмінність між властивостями Safe (Безпечний) та Idempotent (Ідемпотентний)?
Відповідь: Метод є Safe, якщо він взагалі не змінює стан даних на сервері (тільки читання: GET, HEAD, OPTIONS). Метод є Idempotent, якщо його повторні ідентичні виклики призводять до того ж кінцевого стану даних на сервері, що й перший виклик. Наприклад, DELETE не є безпечним (він модифікує БД), але він ідемпотентний (після 1-го або 100-го виклику сутність у БД видалена).
2. Якщо другий виклик DELETE /users/1 повертає 404 Not Found, чи порушується ідемпотентність?
Відповідь: Ні, не порушується. Ідемпотентність за RFC 9110 визначається кінцевим станом даних на сервері (Resource State), а не статус-кодом HTTP-відповіді. Після першого і після другого запиту користувача з ID 1 в системі немає — отже, стан сервера не змінився, і метод ідемпотентний.
3. Навіщо потрібен метод HEAD і коли його використовують на практиці?
Відповідь: Метод HEAD повертає абсолютно ідентичні заголовки, що й GET, але з гарантовано порожнім тілом відповіді. Він незамінний для:
- Перевірки доступності ресурсу (
200vs404) без передачі зайвого трафіку. - Перевірки розміру файлу перед завантаженням через заголовок
Content-Length. - Перевірки валідності клієнтського кешу через перевірку заголовків
ETagабоLast-Modified.
4. Що станеться, якщо в запиті PUT не передати одне з існуючих полів сутності?
Відповідь: За контрактом PUT виконує повну заміну ресурсу. Сервер зобов’язаний затерти непередане поле в null (або встановити дефолтне значення). Якщо клієнт хоче оновити тільки частину полів, не чіпаючи інші, він зобов’язаний використовувати метод PATCH.
🎯 Interview Cheat Sheet
30-секундна відповідь
У REST використовуються 5 базових методів HTTP (RFC 9110):
GET— читання ресурсу (Safe, Idempotent).POST— створення підпорядкованого ресурсу або тригер дії (Неідемпотентний).PUT— повна заміна ресурсу за вказаним URI (Idempotent).PATCH— часткове оновлення полів ресурсу (зазвичай неідемпотентний).DELETE— видалення ресурсу (Idempotent).Допоміжні методи:
HEAD(заголовки без тіла для перевірки кешу та розміру) таOPTIONS(опитування можливостей сервера та CORS Preflight).
Червоні прапорці (чого категорично не можна говорити)
- ❌ «
PUTіPATCHроблять одне й те саме, це синоніми» —PUTповністю заміщує ресурс,PATCHоновлює тільки вказані поля. - ❌ «
DELETEнеідемпотентний, тому що другий запит повертає помилку 404» — статус відповіді може змінюватися, важливий стан сервера. - ❌ «
GETможна використовувати для видалення або зміни записів у базі» — грубе порушення специфікації Safe Methods. - ❌ «Метод
POSTідемпотентний з коробки» —POSTпринципово неідемпотентний і безIdempotency-Keyдублює дії при повторах.