Ответ
Технически — да, но с точки зрения RESTful-архитектуры и семантики HTTP — это противоречивая практика.
Стандартный подход (REST):
- Метод
POSTна коллекцию (например,/api/users) предназначен для создания нового ресурса, идентификатор которого должен быть сгенерирован на стороне сервера (часто в БД). Клиент не должен знать или указывать этот id заранее. - Успешный ответ
201 Createdобычно содержит заголовокLocationс URL нового ресурса (например,/api/users/123) и может включать созданный объект в теле.
Пример на Express.js:
app.post('/api/users', async (req, res) => {
const userData = req.body; // { name: 'Alice', email: 'alice@example.com' }
// id НЕ ожидается в userData
const newUser = await db.users.create(userData); // Сервер генерирует id
res.status(201).location(`/api/users/${newUser.id}`).json(newUser);
});
Когда передача id в POST может иметь смысл (но лучше избегать):
- Импорт данных: При массовом импорте существующих данных из другой системы, где id нужно сохранить.
- Специфичная бизнес-логика: Если идентификатор является не техническим ключом БД, а частью бизнес-данных (например, артикул товара, который задает клиент).
Альтернативы:
- Для операций, где клиент определяет ключ ресурса, более семантически верным является метод
PUTна конкретный URL (например,PUT /api/users/alices-article-number).PUTидемпотентен и означает «создать или полностью заменить ресурс по данному идентификатору».
В моих проектах на Node.js я строго следую принципам REST: POST для создания без указания id, PUT/PATCH для обновления по известному id. Это делает API предсказуемым и понятным для всех разработчиков.
Ответ 18+ 🔞
А, ну вот это интересный вопрос, прям в точку! Смотри, технически-то твой сервак, конечно, может сожрать POST-запрос с id в теле. Код проглотит, запишет в базу — и вроде бы работает. Но с точки зрения REST, это как заехать в пиццерию и принести с собой свою готовую пиццу, требуя, чтобы её просто разогрели и дали тебе чек. Ну то есть странно, ёпта.
Каноничный, правильный подход (REST):
- Метод
POSTна коллекцию (типа/api/users) — это по сути крик «Создай мне что-то новое, а какой там id вылезет — твои проблемы, я потом узнаю». - Сервер сам генерирует id (чаще всего в БД), а в ответе любезно отдаёт
201 Createdи ссылку на новорожденного в заголовкеLocation. Клиент доволен, архитектура не плачет.
Вот как это выглядит в коде, без всяких самодеятельностей:
app.post('/api/users', async (req, res) => {
const userData = req.body; // { name: 'Alice', email: 'alice@example.com' }
// id НЕ ожидается в userData
const newUser = await db.users.create(userData); // Сервер генерирует id
res.status(201).location(`/api/users/${newUser.id}`).json(newUser);
});
А когда эта дичь с id в POST может прокатить? Ну, бывает же, овердохуища случаев:
- Импорт данных: Тащишь тонну записей из старой системы, и там у каждой уже есть свой родной, любимый id, который надо сохранить. Делать нечего.
- Хитрая бизнес-логика: Если твой «айдишник» — это не скучный автоинкремент, а, скажем, артикул товара или номер договора, который придумывает сам клиент. Это уже часть данных, а не техническая метка.
Но слушай сюда, главное: если уж клиенту так приспичило самому указать, где и под каким ключом будет лежать ресурс — есть же метод PUT, ядрёна вошь! Он для этого и создан. PUT на конкретный URL — это чёткое заявление: «Создай или полностью перезапиши ресурс вот по этому адресу». И он идемпотентный, что всем разработчикам на руку.
В общем, в своих проектах я придерживаюсь простого правила: POST — это «создай, а id дашь потом», PUT/PATCH — «работай с тем, что я уже нашёл». Так API становится предсказуемым, и доверия к нему ебать не ноль, а вполне себе нормальный уровень. А то начнёшь позволять вольности — потом сам от себя охуеешь, разбирая, что где и как работает.