null인가 필드 생략인가
핵심 요약: `null`은 필드가 존재하지만 값이 없다는 뜻이고, 생략은 필드가 존재하지 않는다는 뜻입니다. PATCH 본문, 설정 병합, 폼 미리 채우기에서 차이가 물립니다.

핵심부터 말하면, 소비자가 "지움"과 "건드리지 않음"을 구분해야 할 때 null을 보내세요. PATCH 본문에서 누락은 필드를 그대로 두고 명시적 null은 지웁니다. 필드마다 하나의 관례를 유지해 응답과 설정 병합이 안정적이게 하세요.
차이
{ "nickname": null }
존재하고 비어 있음. 소비자는 필드가 명시적으로 지워졌음을 압니다.
{ }
없음. 소비자는 "한 번도 설정 안 됨"과 "지원 안 됨"을 구분할 수 없습니다.
JavaScript에서 구분은 구체적입니다:
'nickname' in obj // false — absent
obj.nickname === null // true — present and null
obj.nickname === undefined // true — both cases
중요한 곳
PATCH 본문. {"nickname": null}은 nickname을 지웁니다. {}는 아무것도 바꾸지 않습니다. 핸들러가 "null"과 "누락"을 같게 취급하면 사용자는 필드를 절대 지울 수 없고 빈 문자열로만 설정할 수 있는데, 이는 다른 것입니다.
값이 아니라 키 존재로 구현하세요:
if (Object.hasOwn(patch, 'nickname')) {
target.nickname = patch.nickname; // null allowed
}
설정 병합. 누락은 기본값을 상속하고 null은 명시적으로 비활성화합니다. Helm과 Kubernetes values가 정확히 이렇게 동작합니다.
폼 미리 채우기. null도 빈 값으로 렌더되고 누락 필드도 그렇지만 제출은 다릅니다. 값이 있다가 지워짐 → null 전송, 한 번도 채우지 않음 → 생략. 구분이 없으면 지우기가 건드리지 않기와 똑같아 보입니다.
관례
| 상황 | 관례 |
|---|---|
| 응답 본문 | null 유지, 안정적 모양, 단순한 타입 |
| PATCH 요청 | null은 지우고, 누락은 유지 |
| PUT(전체 교체) | 누락은 삭제를 뜻함, 전체 문서가 교체됨 |
| 설정 병합 | 누락 = 기본값, null = 비활성화 |
| 데이터베이스 | 알 수 없음이나 해당 없음은 null, 알려진 빈 값은 '' |
응답 모양을 안정적으로 유지하세요. 일부 항목에 avatar가 있고 다른 항목에는 없는 목록은 모든 호출 지점에서 'avatar' in item 검사를 강제합니다. avatar: null이 소비하기 쉽습니다.
하지 말아야 할 세 가지
null에 ""를 쓰지 마세요. 빈 닉네임과 설정되지 않은 닉네임은 대부분 도메인에서 다른 상태입니다.
센티널로 0이나 -1을 쓰지 마세요. 0은 합법적인 숫자이고 센티널이 계산하는 모든 평균을 오염시킵니다.
엔드포인트마다 관례를 섞지 마세요. 두 관례는 모든 클라이언트에 두 코드 경로를 뜻합니다.
FAQ
null과 누락 필드 중 무엇이 결정하나?
소비자가 "명시적으로 지움"과 "한 번도 설정 안 됨"을 구분해야 하는지 물으세요. PATCH 본문에서는 반드시 그래야 하므로 null은 지우고 누락은 유지합니다. 응답에서는 null을 유지하면 모양이 안정적이고 클라이언트 타입이 단순해집니다.
PATCH 엔드포인트가 지우기와 그대로 두기를 어떻게 구분하나?
값이 아니라 키 존재를 확인하세요. Object.hasOwn(patch, 'nickname')은 필드가 전송되었음을 알려 주고, 그때만 null을 포함해 할당하세요. 핸들러가 null과 누락을 같게 취급하면 사용자는 필드를 절대 지울 수 없고 빈 문자열로만 대체할 수 있습니다.
응답 본문이 왜 null을 유지해야 하나?
안정적 모양이면 클라이언트가 모든 선택 키에 'avatar' in item 검사를 할 필요가 없습니다. 일부 목록 항목이 avatar를 지니고 다른 항목이 생략하면 그 검사가 모든 호출 지점에 중복되고 틀리기 쉽습니다.