web-dev-qa-db-fra.com

Manière standardisée de sérialiser JSON pour interroger une chaîne?

J'essaie de créer un API reposant et je ne parviens pas à mettre en série les données JSON sur un HTTP query string.

Un certain nombre d'arguments obligatoires et facultatifs doivent être passés dans la demande, par exemple (représenté sous la forme d'un objet JSON ci-dessous):

{
   "-columns" : [
      "name",
      "column"
   ],
   "-where" : {
      "-or" : {
         "customer_id" : 1,
         "services" : "schedule"
      }
   },
   "-limit" : 5,
   "return" : "table"
}

Je dois prendre en charge un grand nombre de clients différents. Je cherche donc un moyen normalisé de convertir cet objet json en chaîne de requête. Y a-t-il un, et à quoi ça ressemble?

Une autre alternative est de permettre aux utilisateurs de simplement transmettre l'objet json dans un corps de message, mais j'ai lu que je devais l'éviter ( HTTP GET avec le corps de la requête ).

Des pensées?

Modifier pour clarification:

Énumérant comment différentes langues encodent l'objet json donné ci-dessus:

  • jQuery en utilisant $.param: -columns [] = nom & -columns [] = colonne & -where [-or] [ID_client] = 1 & -where [-or] [services] = horaire & -limit = 5 & retour = colonne
  • PHP en utilisant http_build_query: -columns [0] = nom & -columns [1] = colonne & -where [-or] [ID_client] = 1 & -where [-or] [services] = horaire & -limit = 5 & retour = colonne
  • Perl en utilisant URI::query_form: -columns = nom & -columns = colonne & -where = HASH (0x59d6eb8) & - limite = 5 & retour = colonne
  • Perl en utilisant complex_to_query: -columns: 0 = nom & -columns: 1 = colonne & -limit = 5 & -where.-or.customer_id = 1 & -where.-or.services = agenda & retour = colonne

jQuery et PHP est très similaire. Perl, qui utilise complex_to_query, leur est également très similaire. Mais aucun ne se ressemble exactement.

50
Andreas

URL-encoder ( https://en.wikipedia.org/wiki/Percent-encoding ) votre texte JSON et le placer dans un seul paramètre de chaîne de requête. par exemple, si vous voulez passer {"val": 1}:

mysite.com/path?json=%7B%22val%22%3A%201%7D

Notez que si votre JSON devient trop long, vous rencontrerez un problème de limitation de longueur d’URL. Dans ce cas, j'utiliserais POST avec un corps (oui, je sais, envoyer un POST lorsque vous voulez aller chercher quelque chose qui n'est pas "pur" et ne correspond pas bien au REST paradigme, mais le langage de requête basé sur JSON spécifique à votre domaine n'est pas non plus).

49
akonsu

Il n'y a pas de norme unique pour JSON pour interroger la sérialisation de chaîne, j'ai donc fait un comparaison de certains sérialiseurs JSON et les résultats sont les suivants:

JSON:    {"_id":"5973782bdb9a930533b05cb2","isActive":true,"balance":"$1,446.35","age":32,"name":"Logan Keller","email":"[email protected]","phone":"+1 (952) 533-2258","friends":[{"id":0,"name":"Colon Salazar"},{"id":1,"name":"French Mcneil"},{"id":2,"name":"Carol Martin"}],"favoriteFruit":"banana"}
Rison:   (_id:'5973782bdb9a930533b05cb2',age:32,balance:'$1,446.35',email:'[email protected]',favoriteFruit:banana,friends:!((id:0,name:'Colon Salazar'),(id:1,name:'French Mcneil'),(id:2,name:'Carol Martin')),isActive:!t,name:'Logan Keller',phone:'+1 (952) 533-2258')
O-Rison: _id:'5973782bdb9a930533b05cb2',age:32,balance:'$1,446.35',email:'[email protected]',favoriteFruit:banana,friends:!((id:0,name:'Colon Salazar'),(id:1,name:'French Mcneil'),(id:2,name:'Carol Martin')),isActive:!t,name:'Logan Keller',phone:'+1 (952) 533-2258'
JSURL:   ~(_id~'5973782bdb9a930533b05cb2~isActive~true~balance~'!1*2c446.35~age~32~name~'Logan*20Keller~email~'logankeller*40artiq.com~phone~'*2b1*20*28952*29*20533-2258~friends~(~(id~0~name~'Colon*20Salazar)~(id~1~name~'French*20Mcneil)~(id~2~name~'Carol*20Martin))~favoriteFruit~'banana)
QS:      _id=5973782bdb9a930533b05cb2&isActive=true&balance=$1,446.35&age=32&name=Logan Keller&[email protected]&phone=+1 (952) 533-2258&friends[0][id]=0&friends[0][name]=Colon Salazar&friends[1][id]=1&friends[1][name]=French Mcneil&friends[2][id]=2&friends[2][name]=Carol Martin&favoriteFruit=banana
URLON:   $_id=5973782bdb9a930533b05cb2&isActive:true&balance=$1,446.35&age:32&name=Logan%20Keller&[email protected]&phone=+1%20(952)%20533-2258&friends@$id:0&name=Colon%20Salazar;&$id:1&name=French%20Mcneil;&$id:2&name=Carol%20Martin;;&favoriteFruit=banana
QS-JSON: isActive=true&balance=%241%2C446.35&age=32&name=Logan+Keller&email=logankeller%40artiq.com&phone=%2B1+(952)+533-2258&friends(0).id=0&friends(0).name=Colon+Salazar&friends(1).id=1&friends(1).name=French+Mcneil&friends(2).id=2&friends(2).name=Carol+Martin&favoriteFruit=banana

Le plus court d'entre eux est notation d'objet URL .

6
niutech

Pourquoi ne pas essayer de les envoyer comme suit:

http://example.com/api/wtf?
[-columns][]=name&
[-columns][]=column&
[-where][-or][customer_id]=1&
[-where][-or][services]=schedule&
[-limit]=5&
[return]=table&

J'ai essayé avec un REST Client enter image description here

Et du côté serveur (Ruby avec Sinatra), j'ai vérifié les paramètres, cela me donne exactement ce que vous voulez. :-)

enter image description here

4
Sagar Ranglani

Une autre option pourrait être node-querystring . Il utilise également un schéma similaire à ceux que vous avez énumérés jusqu'à présent.

Il est disponible à la fois dans npm et bower, c'est pourquoi je l'utilise.

4
wprl