Bonjour à tous
Suite à quelques discussions sur des sujets voisins, voici quelques éléments sur le transport de données via JSON.
JSON est à la base une notation directement issue de javascript. Elle s'est émancipée de cette origine mais en garde tout de même des traces.
Les types transportés par JSON sont les types de base de javascript : String, Number, Boolean et les types structurés Array et Object.
JSON ne prévoit pas de typer plus fortement les données transmises.
Pas de date, char (date est une classe qui est dans le moteur JS mais pas dans le langage)
Encore moins de structure définie par l'utilisateur ni de classes (Javascript n'est pas un langage à base de classe mais un langage à prototype, donc on peut lui ajouter mais ce n'est pas dans sa nature)
Du coup il n'y a rien de précis sur le sujet.
Mais certains utilisent JSON pour inclure des informations de type.
La principale que j'ai trouvée consiste à inclure des noms de classe.
J'ai trouvé deux écoles : la première vient du monde java. Elle consiste à ajouter en "root élément" le nom de la classeC'est simple mais du coup la structure est changée. Là un un AJAX attendait
Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part {"MyPojo":{"id":4, "name":"test"}}il reçoit un niveau hiérarchique de plus.
Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part {"id":4, "name":"test"}
Côté PHP (Zend en autre) la solution proposée consiste à ajouter un membre de plus à l'objetCela implique que l'objet ne peut avoir un membre __ClassName.
Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part {"__ClassName":"MyPojo","id":4, "name":"test"}
C'est la même approche qu'utilise objective j mais avec une clef différentej'ai trouvé un exemple (non public désolé) qui code aussi les types mais ça devient lourd
Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part {"__objjClassName":"MyPojo","id":4, "name":"test"}o pour object, i pour int s pour string etc
Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part {"o":"MyPojo":[{"s":"id", "i":45},{"s":"name", "s":"test"};]}
Dans ce cas il faut écrire un parseur spécifique pour récupérer son info car il ne contient pas le JSON "standard" dans ses parties.
Cette solution est très proche de php serializeDans le même ordre d'idées mais en mixant les deux approches on peut envisager de transporter la description des types dans un membre et les données ensuite. Mais je n'ai rien trouvé de tel
Code php : Sélectionner tout - Visualiser dans une fenêtre à part O:6:"MyPojo":2:{s:2:"id";i:45;s:4:"name";s:4:"test";}Tout cela ajoute de la lourdeur et de la complexité. Comment traiter une description dont les donnée ne correspondent pas, un int à la place d'un string par exemple etc.
Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 {"__Types":{"O":{"ClassName":"MyPojo",{"i":"id","s":"name"}}}, "id":4, "name":"test"}
Enfin pour finir une autre approche du problème est d'en passer par un schéma. Tout comme un XML se décrit par un xsd un JSON peut être décrit par un schéma lui même définit en JSONCe schéma étant chargé une seule fois indépendamment des données pour permettre au parser de faire des vérification plus strictes
Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 {"complexType":{ "name":"MyPojo", "all":[ {"element" {"name":"id", "type":"integer"}} {"element" {"name":"name", "type":"string" }} {"element" { "name":"date", "type":"Date", "restriction":{ "base":"string", "pattern":{"value":"[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}:[0-9]{3}"} } }} ] }}
L'utilisation d'une notation commedevenant suffisante pour typer plus fortement les données.
Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part {"__ClassName":"MyPojo","id":4, "name":"test", "date":"2010-11-22 10:58:12:532"}
Bien sûr tout cela n'est pas normalisé et est un peu à l'opposé de la philosophie de base de JSON qui est par nature (très) faiblement typé
La solution "root élément" est facile à implémenter côté serveur et nécessite une adaptation côté client pour récupérer les donnes.
la solution "membre" est facile à mettre en œuvre côté serveur et est ignorée par Ajax, elle ne nécessite une adaptation côté client que si l'on veut exploiter les noms de classe.
Les deux ne typent pas les membres.
La solution que j'ai trouvée qui ressemble à php sérialize est plus complexe à mettre en œuvre côté serveur et me parait très complexe côté client. Elle nécessite d'écrire un PostParser qui après le parser JSON reconstruit l'objet final.
La solution mixte que j'ai extrapolée dans cet article est presque aussi lourde mais moyennant une petite adaptation on peut récupérer les données comme dans un JSON standard. Je ne voit pas l'utilité de faire cela.
Transporter le type dans les données est pour moi contre-productif, lourd et complexe.
Je pense que si l'on a un besoin de typage fort une description genre schéma (voire plus simple) me paraît plus appropriée car elle n'influence pas ou peu le trafic. Extjs utilise ce genre de description:A+JYT
Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 {fields: [ {name: 'company'}, {name: 'price', type: 'float'}, {name: 'change', type: 'float'}, {name: 'pctChange', type: 'float'}, {name: 'lastChange', type: 'date', dateFormat: 'n/j h:ia'} ]}
Partager