null u omitir el campo
En resumen: `null` dice que el campo existe sin valor; omitirlo dice que el campo no existe. Los cuerpos PATCH, la fusión de configuración y el relleno previo de formularios son donde la diferencia muerde.

En resumen: envía null cuando el consumidor deba distinguir «borrado» de «intacto»; en un cuerpo PATCH, la omisión deja el campo intacto y un null explícito lo borra; y mantén una convención por campo para que las respuestas y las fusiones de configuración sigan siendo estables.
La diferencia
{ "nickname": null }
Presente, vacío. El consumidor sabe que el campo se borró explícitamente.
{ }
Ausente. El consumidor no puede distinguir «nunca establecido» de «no admitido».
En JavaScript la distinción es concreta:
'nickname' in obj // false — absent
obj.nickname === null // true — present and null
obj.nickname === undefined // true — both cases
Dónde importa
Cuerpos PATCH. {"nickname": null} borra el apodo. {} no cambia nada. Si el manejador trata «null» y «falta» igual, los usuarios nunca pueden borrar el campo: solo pueden establecer una cadena vacía, que es una cosa distinta.
Implaméntalo con la presencia de la clave, no con el valor:
if (Object.hasOwn(patch, 'nickname')) {
target.nickname = patch.nickname; // null allowed
}
Fusión de configuración. La omisión hereda el valor predeterminado; null lo desactiva explícitamente. Así se comportan exactamente los valores de Helm y Kubernetes.
Relleno previo de formularios. Un null se muestra como vacío y también un campo faltante, pero el envío difiere: tenía un valor, ahora borrado → envía null; nunca se rellenó → omítelo. Sin la distinción, borrar parece idéntico a no tocar.
Convenciones
| Situación | Convención |
|---|---|
| Cuerpos de respuesta | Mantén null; forma estable, tipos más simples |
| Peticiones PATCH | null borra, la omisión conserva |
| PUT (reemplazo completo) | Omitir significa eliminar: se reemplaza todo el documento |
| Fusión de configuración | Omitir = predeterminado, null = desactivado |
| Base de datos | null para desconocido o no aplicable; '' para vacío conocido |
Mantén estables las formas de respuesta. Una lista en la que algunos elementos llevan avatar y otros no obliga a comprobar 'avatar' in item en cada punto de llamada. avatar: null es más fácil de consumir.
Tres cosas que no hacer
No uses "" para null. Un apodo vacío y un apodo sin establecer son estados distintos en la mayoría de los dominios.
No uses 0 o -1 como centinelas. El cero es un número legítimo, y el centinela corrompe todas las medias que calcules.
No mezcles convenciones por endpoint. Dos convenciones significan dos rutas de código en cada cliente.
FAQ
¿Qué decide entre null y un campo omitido?
Pregúntate si el consumidor necesita distinguir «borrado explícitamente» de «nunca establecido». En un cuerpo PATCH debe hacerlo, así que null borra y la ausencia conserva; en las respuestas, mantener null hace que la forma sea estable y los tipos del cliente más simples.
¿Cómo distingue un endpoint PATCH entre borrar y dejar intacto?
Comprueba la presencia de la clave, no el valor: Object.hasOwn(patch, 'nickname') te dice que el campo se envió, y solo entonces asígnalo, incluido null. Si el manejador trata null y la ausencia igual, los usuarios nunca pueden borrar el campo y solo pueden recurrir a una cadena vacía.
¿Por qué deberían los cuerpos de respuesta mantener null?
Una forma estable significa que los clientes no necesitan una comprobación 'avatar' in item para cada clave opcional. Cuando algunos elementos de la lista llevan avatar y otros lo omiten, esa comprobación se duplica en cada punto de llamada y es fácil equivocarse.