web-dev-qa-db-fra.com

Représentant null en JSON

Quelle est la méthode recommandée pour renvoyer des valeurs NULL en JSON? Existe-t-il une préférence différente pour les primitives?

Par exemple, si mon objet sur le serveur a un Integer appelé "myCount" sans valeur, le JSON le plus correct pour cette valeur serait:

{}

ou

{
    "myCount": null
}

ou

{
    "myCount": 0
}

Même question pour Strings - si j'ai une chaîne vide "myString" sur le serveur, le meilleur JSON:

{}

ou

{
    "myString": null
}

ou

{
    "myString": ""
}

ou (Seigneur aide-moi)

{
    "myString": "null"
}

J'aime la convention selon laquelle les collections sont représentées dans le JSON sous la forme d'une collection vide http://jtechies.blogspot.nl/2012/07/item-43-return-empty-arrays-or.html

Un tableau vide serait représenté:

{
    "myArray": []
}

EDIT Résumé

L'argument des "préférences personnelles" semble réaliste, mais à courte vue, en tant que communauté, nous consommerons un nombre toujours croissant de services/sources disparates. Les conventions relatives à la structure JSON permettraient de normaliser la consommation et la réutilisation desdits services. En ce qui concerne l'établissement d'une norme, je suggérerais d'adopter la plupart des conventions de Jackson à quelques exceptions près:

  • Les objets sont préférés aux primitives.
  • Les collections vides sont préférées à null.
  • Les objets sans valeur sont représentés par null.
  • Les primitives retournent leur valeur.

Si vous renvoyez un objet JSON avec des valeurs généralement nulles, vous pouvez avoir un candidat pour le refactoring dans plusieurs services.

{

    "value1": null,

    "value2": null,

    "text1": null,

    "text2": "hello",

    "intValue": 0, //use primitive only if you are absolutely sure the answer is 0

    "myList": [],

    "myEmptyList": null, //NOT BEST PRACTICE - return [] instead

    "boolean1": null, //use primitive only if you are absolutely sure the answer is true/false

    "littleboolean": false

}

Le JSON ci-dessus a été généré à partir de la classe Java suivante.

package jackson;

import Java.util.ArrayList;
import Java.util.List;

import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonApp {

    public static class Data {

        public Integer value1;

        public Integer value2;

        public String text1;

        public String text2 = "hello";

        public int intValue;

        public List<Object> myList = new ArrayList<Object>();

        public List<Object> myEmptyList;

        public Boolean boolean1;

        public boolean littleboolean;

    }

    public static void main(String[] args) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        System.out.println(mapper.writeValueAsString(new Data()));
    }
}

Dépendance Maven:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.3.0</version>
</dependency>
342
pherris

Évaluons l'analyse de chacun:

http://jsfiddle.net/brandonscript/Y2dGv/

var json1 = '{}';
var json2 = '{"myCount": null}';
var json3 = '{"myCount": 0}';
var json4 = '{"myString": ""}';
var json5 = '{"myString": "null"}';
var json6 = '{"myArray": []}';

console.log(JSON.parse(json1)); // {}
console.log(JSON.parse(json2)); // {myCount: null}
console.log(JSON.parse(json3)); // {myCount: 0}
console.log(JSON.parse(json4)); // {myString: ""}
console.log(JSON.parse(json5)); // {myString: "null"}
console.log(JSON.parse(json6)); // {myArray: []}

Le tl; dr ici:

Le fragment de la variable json2 est le moyen la spécification JSON indique que null devrait être représenté. Mais comme toujours, cela dépend de ce que vous faites - parfois, la "bonne" façon de le faire ne fonctionne pas toujours dans votre situation. Utilisez votre jugement et prenez une décision éclairée.


JSON1 {}

Cela retourne un objet vide. Il n'y a pas de données là-bas, et cela va seulement vous dire que la clé que vous cherchez (que ce soit myCount ou quelque chose d'autre) est de type undefined.


JSON2 {"myCount": null}

Dans ce cas, myCount est défini, bien que sa valeur soit null. Ceci est pas la même chose que "pas undefined et pas null", et si vous testiez une condition ou l'autre, cela pourrait réussir alors que JSON1 échouerait.

C'est la manière définitive de représenter null par la spécification JSON .


JSON3 {"myCount": 0}

Dans ce cas, myCount vaut 0. Ce n'est pas la même chose que null et ce n'est pas la même chose que false. Si votre instruction conditionnelle évalue myCount > 0, alors cela peut être intéressant. De plus, si vous exécutez des calculs basés sur la valeur indiquée, 0 peut être utile. Si vous essayez de tester null, cela ne fonctionnera pas du tout.


JSON4 {"myString": ""}

Dans ce cas, vous obtenez une chaîne vide. Encore une fois, comme pour JSON2, c'est défini, mais c'est vide. Vous pouvez tester if (obj.myString == "") mais vous ne pouvez pas tester null ni undefined.


JSON5 {"myString": "null"}

Cela vous causera probablement des problèmes, car vous définissez la valeur string sur null; dans ce cas, obj.myString == "null" mais c'est pas == null.


JSON6 {"myArray": []}

Cela vous dira que votre tableau myArray existe, mais qu'il est vide. Ceci est utile si vous essayez d'effectuer un compte ou une évaluation sur myArray. Par exemple, supposons que vous vouliez évaluer le nombre de photos postées par un utilisateur. Vous pouvez faire myArray.length et renvoyer 0: défini, mais aucune photo.

301
brandonscript

null n'est pas zéro. Ce n'est pas une valeur, en soi : c'est une valeur en dehors du domaine de la variable indiquant des données manquantes ou inconnues.

Il n'y a qu'un seul moyen de représenter null en JSON. Selon les spécifications ( RFC 4627 et json.org ):

2.1. Valeurs 
 
 Une valeur JSON DOIT être un objet, un tableau, un nombre ou une chaîne, ou l'un des 
 Des trois noms littéraux suivants: 
 
. false null true 

enter image description here

187
Nicholas Carey

Il n'y a qu'un seul moyen de représenter null; c'est-à-dire avec null.

console.log(null === null);   // true
console.log(null === true);   // false
console.log(null === false);  // false
console.log(null === 'null'); // false
console.log(null === "null"); // false
console.log(null === "");     // false
console.log(null === []);     // false
console.log(null === 0);      // false

C'est-à-dire; Si l'un des clients qui utilisent votre représentation JSON, utilisez l'opérateur ===. cela pourrait être un problème pour eux.

aucune valeur

Si vous voulez indiquer que vous avez un objet dont l'attribut myCount n'a pas de valeur:

{ "myCount": null }

aucun attribut/attribut manquant

Et si vous transmettez que vous avez un objet sans attribut:

{}

Le code client essaiera d'accéder à myCount et d'obtenir undefined; Ce n'est pas là.

collection vide

Que se passe-t-il si vous indiquez que vous avez un objet avec un attribut myCount qui est une liste vide:

{ "myCount": [] }
21
dnozay

J'utiliserais null pour montrer qu'il n'y a pas de valeur pour cette clé particulière. Par exemple, utilisez null pour indiquer que "le nombre de périphériques de votre ménage qui se connecte à Internet" est inconnu.

D'autre part, utilisez {} si cette clé n'est pas applicable. Par exemple, vous ne devez pas afficher de compte, même si null, à la question "Nombre de voitures disposant d'une connexion Internet active" est demandé à une personne ne possédant aucune voiture.

J'éviterais de remplacer une valeur par défaut, à moins que cette valeur par défaut ait du sens. Bien que vous puissiez décider d'utiliser null pour ne représenter aucune valeur, n'utilisez jamais "null" pour le faire.

14
marcoseu

Je choisirais "par défaut" pour le type de données de la variable (null pour les chaînes/objets, 0 pour les nombres), mais vérifierais effectivement quel code sera consommé par l'objet. N'oubliez pas qu'il y a parfois une distinction entre null/default et "non présent".

Check out modèle d'objet null - Parfois, il est préférable de passer un objet spécial au lieu de null (c'est-à-dire [] array au lieu de null pour les tableaux ou "" pour les chaînes).

7
Alexei Levenkov

C'est un choix personnel et situationnel. La chose importante à retenir est que la chaîne vide et le nombre zéro sont conceptuellement distincts de null.

Dans le cas d'un count vous voulez probablement toujours un nombre valide (sauf si le count est inconnu ou indéfini), mais dans le cas des chaînes, qui sait? La chaîne vide pourrait moyenne quelque chose dans votre application. Ou peut-être que non. C'est à vous de décider.

2
Wayne Burkett

Selon la spécification JSON , le conteneur le plus externe ne doit pas obligatoirement être un dictionnaire (ou un "objet"), comme l'implique la plupart des commentaires ci-dessus. Il peut aussi s'agir d'une liste ou d'une valeur nue (chaîne, nombre, booléen ou null). Si vous souhaitez représenter une valeur NULL en JSON, l'intégralité de la chaîne JSON (à l'exception des guillemets contenant la chaîne JSON) est simplement null. Pas d'accolades, pas de crochets, pas de guillemets. Vous pouvez spécifier un dictionnaire contenant une clé avec une valeur nulle ({"key1":null}) ou une liste avec une valeur nulle ([null]), mais ce ne sont pas des valeurs nulles elles-mêmes - ce sont des dictionnaires et des listes corrects. De même, un dictionnaire vide ({}) ou une liste vide ([]) conviennent parfaitement, mais ne sont pas non plus nuls.

En Python:

>>> print json.loads('{"key1":null}')
{u'key1': None}
>>> print json.loads('[null]')
[None]
>>> print json.loads('[]')
[]
>>> print json.loads('{}')
{}
>>> print json.loads('null')
None
0
iggie