Ответ
Технически это возможно реализовать, но это считается антипаттерном и нарушением семантики REST API.
Почему это плохая практика:
Метод PUT предназначен для полной замены ресурса по конкретному, известному URI. Он должен быть идемпотентным, то есть многократное выполнение одного и того же запроса должно приводить к одному и тому же состоянию ресурса.
При попытке обновить несколько ресурсов одним PUT-запросом возникают проблемы:
- Нарушение семантики:
PUTработает с одним ресурсом. Например,PUT /users/123заменяет пользователя с ID 123. Какой URI использовать для замены и пользователя, и продукта одновременно?PUT /batch-updateсемантически некорректен. - Потеря идемпотентности: Если часть операции (например, обновление пользователя) пройдет успешно, а другая (обновление продукта) — нет, повторный запрос приведет к другому результату, нарушая принцип идемпотентности.
- Сложность обработки ошибок: Атомарность операции становится проблемой. Если один из объектов не удалось обновить, нужно ли откатывать остальные изменения?
Неправильный пример (как делать не надо):
# Этот запрос семантически неверен для PUT
PUT /api/resources
Content-Type: application/json
{
"user": {"id": 1, "name": "Alice", "email": "alice@example.com"},
"product": {"id": 42, "name": "Laptop", "price": 1200}
}
Рекомендация:
Для массовых или пакетных операций всегда используйте метод POST. Он специально предназначен для сценариев, которые не укладываются в простую CRUD-модель (GET, PUT, DELETE).
Ответ 18+ 🔞
А, слушай, смотри, вот тут такой вопрос подъехал — можно ли впихнуть обновление кучи разных сущностей в один PUT-запрос? Технически-то, конечно, можно, блядь, всё можно, если очень захотеть. Но это будет такой пиздец, такая архитектурная дичь, что потом сам себя в сраку засунешь, когда начнёшь это поддерживать.
Вот в чём, блядь, корень зла. Метод PUT — он же не просто так придуман. Он как молоток: один гвоздь — один удар. Он для полной замены одного конкретного ресурса, у которого есть свой чёткий адрес. И он должен быть идемпотентным, то есть сколько раз ни долби — результат один и тот же. Представь, ты пишешь одно и то же письмо сто раз — хуйня какая-то выходит, но в итоге в ящике лежит одно письмо, а не сто.
А теперь попробуй этим же молотком, блядь, сразу два гвоздя забить. Получается херня:
- Семантика летит в пизду. Какой URI ты укажешь?
PUT /users/123— понятно, это пользователь. АPUT /update-user-and-product— это уже не ресурс, а какая-то мартышлюшка, операция.PUTтак не работает, ёпта! - Идемпотентность накрывается медным тазом. Допустим, пользователя ты обновил, а продукт — нет, потому что цена отрицательная. Ты запрос повторил — а пользователя-то уже обновили! Оп, результат другой. Всё, приехали, принцип нарушен, пидары налетели.
- С ошибками ебаться до посинения. Один объект прошел, второй — нет. Что делать? Откатывать первого? А если нельзя? Короче, терпения ноль ебать, пока разберёшься.
Вот смотри, как делать НЕ НАДО, даже не думай:
# Этот запрос — чистой воды пиздопроебина. Не делай так!
PUT /api/resources
Content-Type: application/json
{
"user": {"id": 1, "name": "Alice", "email": "alice@example.com"},
"product": {"id": 42, "name": "Laptop", "price": 1200}
}
А как надо-то, спросишь?
Да всё просто, как три копейки! Для таких пакетных, хитрожопых операций есть же старый добрый POST. Он именно для этого и создан — делать что-то, что в простые рамки GET/PUT/DELETE не лезет.
Сделай себе нормальный эндпоинт для пакетных операций и шли туда POST-запрос. И спи спокойно. Всё по канону, все довольны, и совесть не гложет, как у того Герасима, блядь, после Муму.