O JSON deve incluir valores nulos [fechado]

89

Estou criando uma API que retorna resultados como JSON. Existe uma prática recomendada atual para saber se devemos incluir chaves no resultado quando o valor é nulo? Por exemplo:

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

ou

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

Como o segundo é menor, estou inclinado a esse estilo, mas não tenho certeza se existe um estilo preferido ou não. Da perspectiva do cliente, parece que os dois estilos seriam funcionalmente equivalentes. Quaisquer prós ou contras de cada um?

Jjathman
fonte
6
É impossível responder corretamente. A resposta correta depende dos requisitos do aplicativo. O OP simplesmente selecionou a resposta que se adequa às suas necessidades. Se seu aplicativo precisa ser capaz de distinguir entre saber se o "isbn" é nulo e se o "isbn" pode não ter sido enviado do servidor por outro motivo, você precisa incluí-lo.
Jacob
@Jacob Embora eu não tenha dito isso, minha intenção com esta pergunta era que o JSON "completo" que representa a resposta estava sendo retornado. Quando um cliente pode presumir que parece não haver diferença funcional entre as duas abordagens. Se a API não retornasse seletivamente as chaves / valores, sim, faria uma grande diferença a abordagem escolhida.
jjathman
o benefício da primeira representação é que o esquema do objeto é preservado, a presença da propriedade não é ambígua com base nos dados. no segundo formato, essa informação é perdida. A especificação JSON, como tal, não exige nenhum dos formatos AFAIK
Surya Pratap

Respostas:

32

O segundo economizará uma pequena quantidade de largura de banda, mas se essa fosse uma preocupação, você também usaria matrizes indexadas em vez de preencher o JSON com chaves. Claramente, ["Foo Bar","Joe Blow"]é muito mais curto do que o que você tem agora.

Em termos de usabilidade, não acho que faça diferença. Em ambos os casos, if(json.isbn)irá saltar para o else. Geralmente não há necessidade de distinguir entre null(nenhum valor) e undefined(nenhum valor fornecido).

Niet the Dark Absol
fonte
7
+1 para Normalmente não há necessidade de distinguir entre nulo (nenhum valor) e indefinido (nenhum valor fornecido). Há até um operador útil para ele != null(não estritamente pretendido)
Esailija
O único caso em que consigo pensar seria testar se um navegador oferece suporte a um determinado tipo de evento. Por exemplo, if( typeof onbeforepaste == "undefined")para ver se onBeforePastehá suporte. Mesmo assim, não faz nenhuma diferença real, já que você pode atribuir eventos o quanto quiser (eles simplesmente não farão nada se não forem suportados).
Niet the Dark Absol
6
Em termos de salvar bytes transferidos, a compactação é muito mais importante do que coisas como matrizes indexadas. web-resource-optimization.blogspot.no/2011/06/… Certifique-se de que é a primeira coisa que você faz. Na maioria dos casos, adicionar coisas como matrizes indexadas em cima disso é o que eu chamaria de otimização prematura. A menos que você esteja enviando GRANDES quantidades de dados. Isso também requer análise adicional, adicionando mais complexidade ao seu aplicativo. O gzip é feito perfeitamente pelo navegador. (presumindo que o cliente seja um navegador)
Martin Hansen
3
Com o HTTPS se tornando a norma do dia (pelo menos para aplicativos com grande base de usuários), a compressão vai para o lado errado. Veja en.wikipedia.org/wiki/CRIME_%28security_exploit%29
Gaurav Vaish
6
Na verdade, eu faria -1 para "Geralmente não há necessidade de distinguir entre nulos" se eu tivesse reputação. A partir de 2 razões: 1. razões para distinguir existem e não são raras 2. a melhor prática é sempre ter valores "bem definidos", o que significa sempre evitar qualquer ambigüidade - 2 significados de 1 valor é sempre mau - deve ser bem claro.
Srneczek
80

Sou fã de sempre incluir null explicitamente, pois isso tem significado. A omissão de uma propriedade deixa ambiguidade.

Contanto que seu protocolo com o servidor seja acordado, qualquer um dos itens acima pode funcionar, mas se você passar nulos do servidor, acredito que isso torna suas APIs mais flexíveis posteriormente.

Também deve mencionar que a função hasOwnProperty do javascript oferece mais informações.

/* 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
fonte
3
Exatamente, mais pessoas precisam entender a diferença entre "", nulo e indefinido. A resposta a esta pergunta depende dos requisitos dos usuários.
Jacob
13
+1. A pessoa do outro lado (que escreveu o código) será mais bem servida por valores explícitos. Eles podem não estar escrevendo JavaScript ;-)
Steve11235
2
Observe que a verificação em relação a null não funciona com ==, === é necessário (porque undefined == null)!
Tommy
exatamente a primeira parte da resposta aceita está tão errada ...
Srneczek
Eu escreveria em "propertyName" in objectFromJSONvez de objectFromJSON.hasOwnProperty("propertyName"). Além disso, se você insiste em usar hasOwnProperty, escreva Object.prototype.hasOwnProperty.call(objectFromJSON, "propertyName")por segurança.
Aadit M Shah
22

Em JavaScript, nullsignifica algo muito diferente de undefined.

Sua saída JSON deve refletir o que é usado e necessário para seu aplicativo no contexto específico de uso dos dados JSON.

Brad
fonte
5
Não há "indefinido" em JSON, então acho que ele pergunta apenas se deve incluir propriedades "vazias" ou não - {"prop":undefined}é diferente de {}.
Bergi
Concordo, estou tentando explicar que, do lado receptor, se ele estiver procurando uma propriedade específica para ser definida como nula, não será. Será indefinido, se deixado de fora.
Brad
11

Definitivamente, você deve incluí-lo se houver necessidade de distinguir entre nulle, undefineduma vez que eles têm dois significados diferentes em Javascript. Você pode pensar nullque significa que a propriedade é desconhecida ou sem sentido e undefinedque significa que a propriedade não existe.

Por outro lado, se não há necessidade de ninguém fazer essa distinção, vá em frente e deixe-a de fora.

Paulo
fonte
0

Acho que não faz diferença quando você usa o JSON como um dado por trás da experiência do usuário.

A diferença aparece nos arquivos JSON-config, quando um usuário deve editar algo manualmente. Ao usar o primeiro exemplo, você dá ao usuário algumas dicas sobre a configuração.

Alexey Kachalov
fonte
1
Você poderia elaborar mais sua resposta adicionando um pouco mais de descrição sobre a solução que você fornece?
abarisone