Каковы семантические различия между HTTP-методами GET и POST в REST API?

«Каковы семантические различия между HTTP-методами GET и POST в REST API?» — вопрос из категории Сети, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

GET и POST — это HTTP-методы с фундаментально разной семантикой, определяемой стандартом RFC 7231.

Характеристика GET POST
Назначение Получение (Read) данных. Создание (Create) или сложная обработка данных.
Идемпотентность Да. Многократный вызов возвращает одинаковый результат и не меняет состояние сервера. Нет. Повторный вызов может создать дублирующиеся ресурсы.
Безопасность Да. Не должен изменять состояние сервера. Нет. Предназначен для изменения состояния.
Кэширование Да. Ответы могут кэшироваться браузером и прокси. Нет. По умолчанию не кэшируется.
Данные запроса Параметры передаются в URL (query string). Данные передаются в теле запроса (body), например, JSON.
Видимость Параметры видны в URL, истории браузера, логах. Данные скрыты в теле запроса.
Ограничение длины Есть (ограничение длины URL браузером/сервером). Практически нет.

Пример в Spring Boot:

// GET: Получить пользователя по ID (идемпотентно и безопасно)
@GetMapping("/users/{id}")
public ResponseEntity<User> getUser(@PathVariable Long id) {
    return userService.findById(id)
            .map(ResponseEntity::ok)
            .orElse(ResponseEntity.notFound().build());
}

// POST: Создать нового пользователя (не идемпотентно)
@PostMapping("/users")
public ResponseEntity<User> createUser(@Valid @RequestBody UserDto userDto) {
    User created = userService.create(userDto);
    URI location = ServletUriComponentsBuilder.fromCurrentRequest()
            .path("/{id}").buildAndExpand(created.getId()).toUri();
    return ResponseEntity.created(location).body(created); // HTTP 201 Created
}

Почему важно: Правильное использование методов — основа предсказуемого, безопасного и эффективного RESTful API.