null или опустить поле
Главное: `null` говорит, что поле существует без значения; опускание говорит, что поля не существует. Тела PATCH, слияние конфигурации и предзаполнение форм — вот где разница кусается.

Главное: отправляйте null, когда потребитель должен отличать «очищено» от «не тронуто» — в теле PATCH опускание оставляет поле как есть, а явный null его очищает — и держите одно соглашение на поле, чтобы ответы и слияния конфигурации оставались стабильными.
Разница
{ "nickname": null }
Присутствует, пусто. Потребитель знает, что поле было явно очищено.
{ }
Отсутствует. Потребитель не может отличить «никогда не устанавливалось» от «не поддерживается».
В JavaScript различие конкретно:
'nickname' in obj // false — отсутствует
obj.nickname === null // true — присутствует и null
obj.nickname === undefined // true — оба случая
Где это важно
Тела PATCH. {"nickname": null} очищает никнейм. {} ничего не меняет. Если обработчик трактует «null» и «отсутствует» одинаково, пользователи никогда не смогут очистить поле — они смогут только установить пустую строку, а это другое.
Реализуйте по наличию ключа, а не по значению:
if (Object.hasOwn(patch, 'nickname')) {
target.nickname = patch.nickname; // null allowed
}
Слияние конфигурации. Опускание наследует значение по умолчанию; null отключает его явно. Именно так ведут себя значения Helm и Kubernetes.
Предзаполнение форм. null отображается как пустое, как и отсутствующее поле, но отправка различается: было значение, теперь очищено → отправить null; никогда не заполнялось → опустить. Без различения очистка выглядит идентично невмешательству.
Соглашения
| Ситуация | Соглашение |
|---|---|
| Тела ответов | Сохранять null; стабильная форма, более простые типы |
| Запросы PATCH | null очищает, опускание сохраняет |
| PUT (полная замена) | Опускание означает удаление — весь документ заменяется |
| Слияние конфигурации | Опускание = по умолчанию, null = отключено |
| База данных | null для неизвестного или неприменимого; '' для известного пустого |
Держите формы ответов стабильными. Список, где у некоторых элементов есть avatar, а у других нет, заставляет проверять 'avatar' in item в каждом месте вызова. avatar: null проще потреблять.
Три вещи, которые не стоит делать
Не используйте "" для null. Пустой никнейм и неустановленный никнейм — разные состояния в большинстве доменов.
Не используйте 0 или -1 как сигнальные значения. Ноль — легитимное число, а сигнальное значение портит каждое среднее, которое вы вычисляете.
Не смешивайте соглашения по конечным точкам. Два соглашения означают два пути кода в каждом клиенте.
Вопросы и ответы
Что решает между null и опущенным полем?
Спросите, нужно ли потребителю различать «явно очищено» и «никогда не установлено». В теле PATCH нужно, поэтому null очищает, а отсутствие сохраняет; в ответах сохранение null делает форму стабильной, а типы клиента проще.
Как конечная точка PATCH отличает очистку от невмешательства?
Проверяйте наличие ключа, а не значение: Object.hasOwn(patch, 'nickname') говорит, что поле было отправлено, и только тогда присваивайте его, включая null. Если обработчик трактует null и отсутствие одинаково, пользователи никогда не смогут очистить поле и смогут только откатиться к пустой строке.
Почему тела ответов должны сохранять null?
Стабильная форма означает, что клиентам не нужна проверка 'avatar' in item для каждого необязательного ключа. Когда у некоторых элементов списка есть avatar, а у других он опущен, эта проверка дублируется в каждом месте вызова и легко ошибается.