¿Debería JSON incluir valores nulos [cerrado]

89

Estoy creando una API que devuelve resultados como JSON. ¿Existe una práctica recomendada actual sobre si debemos incluir claves en el resultado cuando el valor es nulo? Por ejemplo:

{
    "title":"Foo Bar",
    "author":"Joe Blow",
    "isbn":null
}

o

{
    "title":"Foo Bar",
    "author":"Joe Blow"
}

Como el segundo es más pequeño, me inclino por este estilo, pero no estoy seguro de si hay un estilo preferido o no. Desde la perspectiva del cliente, parece que ambos estilos serían funcionalmente equivalentes. ¿Pros o contras de cada uno?

jjathman
fuente
6
Es imposible responder a esto correctamente. La respuesta correcta depende de los requisitos de la aplicación. El OP simplemente ha seleccionado la respuesta que se adapta a sus necesidades. Si su aplicación necesita poder distinguir entre saber si el "isbn" es nulo o si el "isbn" puede no haber sido enviado desde el servidor por otro motivo, debe incluirlo.
Jay
@Jacob Aunque no lo dije, mi intención con esta pregunta era que se devolviera el JSON "completo" que representa la respuesta. Cuando un cliente puede asumir que parece no haber diferencia funcional entre los dos enfoques. Si la API no devuelve claves / valores de forma selectiva, entonces sí, haría una gran diferencia el enfoque que se adopte.
jjathman
el beneficio de la primera representación es que se conserva el esquema del objeto, la presencia de la propiedad no es ambigua según los datos. en el segundo formato esta información se pierde. La especificación JSON como tal no exige ningún formato AFAIK
Surya Pratap

Respuestas:

32

El segundo ahorrará una pequeña cantidad de ancho de banda, pero si eso fuera un problema, también usaría matrices indexadas en lugar de llenar el JSON con claves. Claramente, ["Foo Bar","Joe Blow"]es mucho más corto de lo que tienes ahora.

En términos de usabilidad, no creo que haya ninguna diferencia. En ambos casos, if(json.isbn)saltará al else. Por lo general, no es necesario distinguir entre null(sin valor) y undefined(sin valor dado).

Niet the Dark Absol
fuente
7
+1 para Normalmente no es necesario distinguir entre nulo (sin valor) e indefinido (sin valor dado). Incluso hay un operador útil para ello != null(no estrictamente previsto)
Esailija
El único caso en el que puedo pensar sería probar si un navegador admite un determinado tipo de evento. Por ejemplo, if( typeof onbeforepaste == "undefined")para ver si onBeforePastees compatible. Incluso entonces, no hay una diferencia real, ya que puede asignar eventos todo lo que desee (simplemente no harán nada si no son compatibles).
Niet the Dark Absol
6
En términos de ahorro de bytes transferidos, la compresión es mucho más importante que cosas como matrices indexadas. web-resource-optimization.blogspot.no/2011/06/… Asegúrese de que sea lo primero que haga. En la mayoría de los casos, agregar cosas como matrices indexadas encima es lo que yo llamaría optimización prematura. A menos que esté enviando GRANDES cantidades de datos. Eso también requiere un análisis adicional, lo que agrega más complejidad a su aplicación. El navegador realiza Gzip sin problemas. (asumiendo que el cliente es un navegador)
Martin Hansen
3
Con HTTPS convirtiéndose en la norma del día (al menos para las aplicaciones con una gran base de usuarios), la compresión se pierde. Ver en.wikipedia.org/wiki/CRIME_%28security_exploit%29
Gaurav Vaish
6
De hecho, haría -1 esto para "Normalmente no hay necesidad de distinguir entre nulos" si tuviera reputación. Por 2 razones: 1. Existen razones para distinguir y no son raras 2. La mejor práctica es tener siempre valores "bien definidos", es decir, evitar siempre cualquier ambigüedad - 2 significados de 1 valor siempre es malo - debería ser bastante claro.
Srneczek
80

Soy fanático de incluir siempre null explícitamente, ya que eso conlleva un significado. Si bien la omisión de una propiedad deja ambigüedad.

Siempre que se acuerde su protocolo con el servidor, cualquiera de los anteriores puede funcionar, pero si pasa nulos desde el servidor, creo que eso hace que sus API sean más flexibles más adelante.

También debería mencionar que la función hasOwnProperty de javascript le da más información.

/* if true object DOES contain the property with *some* value */
if( objectFromJSON.hasOwnProperty( "propertyName" ) )

/* if true object DOES contain the property and it has been set to null */
if( jsonObject.propertyName === null )

/* if true object either DOES NOT contain the property
   OR
   object DOES contain the property and it has been set to undefined */
if( jsonObject.propertyName === undefined )
Rushkeldon
fuente
3
Exactamente, más personas necesitan comprender la diferencia entre "", nulo e indefinido. La respuesta a esta pregunta depende de los requisitos de los usuarios.
Jay
13
+1. La persona del otro lado (que escribió el código) estará mejor atendida por valores explícitos. Puede que no estén escribiendo JavaScript ;-)
Steve11235
2
Tenga en cuenta que la comprobación con nulo no funciona con ==, se requiere === (porque undefined == null).
Tommy
exactamente la primera parte de la respuesta aceptada es tan incorrecta ...
Srneczek
Escribiría en "propertyName" in objectFromJSONlugar de objectFromJSON.hasOwnProperty("propertyName"). Además, si insiste en usar hasOwnProperty, escriba Object.prototype.hasOwnProperty.call(objectFromJSON, "propertyName")por seguridad.
Aadit M Shah
22

En JavaScript, null significa algo muy diferente a undefined.

Su salida JSON debe reflejar lo que su aplicación usa y necesita en el contexto específico del uso de datos JSON.

Puntilla
fuente
5
No hay "indefinido" en JSON, por lo que creo que solo pregunta si incluir propiedades "vacías" o no, {"prop":undefined}es diferente de {}.
Bergi
De acuerdo, estoy tratando de explicar que en el extremo receptor, si está buscando una propiedad específica que se establezca en nula, no lo será. No estará definido, si se deja fuera.
Brad
11

Definitivamente debe incluirlo si hay alguna necesidad de distinguir entre ellos nully undefinedya que tienen dos significados diferentes en Javascript. Puede pensar nullque significa que la propiedad es desconocida o sin sentido, y undefinedque significa que la propiedad no existe.

Por otro lado, si no hay necesidad de que nadie haga esa distinción, entonces déjela fuera.

Paul
fuente
0

Creo que no hay diferencia cuando usa JSON como un dato detrás de la experiencia del usuario.

La diferencia aparece en los archivos JSON-config, cuando un usuario debe editar algo a mano. Cuando usa el primer ejemplo, le da al usuario una pista sobre la configuración.

Alexey Kachalov
fuente
1
¿Podría elaborar más su respuesta agregando un poco más de descripción sobre la solución que proporciona?
abarisone