¿Forma estandarizada de serializar JSON a la cadena de consulta?


Estoy tratando de construir un restful API y estoy luchando sobre cómo serializar JSON datos a un HTTP query string.

Hay una serie de argumentos obligatorios y opcionales que deben pasarse en la solicitud, por ejemplo (representado como un objeto JSON a continuación):

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

Necesito admitir varios clientes diferentes, por lo que estoy buscando una forma estandarizada de convertir este objeto json en una cadena de consulta. Hay uno, y ¿cómo se ve?

Otra alternativa es permitir a los usuarios simplemente pasar el objeto json en un cuerpo del mensaje, pero leí que debería evitarlo (HTTP GET with request body).

¿Algún pensamiento?

Editar para clarificación:

Listando cómo algunos lenguajes diferentes codifican el objeto json dado arriba:

  • jQuery con $.param: -columns[]=name&-columns[]=column&-where[-or][customer_id]=1&-where[-or][services]=schedule&-limit=5&return=column
  • PHP usando http_build_query: -columns[0]=name&-columns[1]=column&-where[-or][customer_id]=1&-where[-or][services]=schedule&-limit=5&return=column
  • Perl usando URI::query_form: - columns = name&-columns=column&-where=HASH(0x59d6eb8)& - limit=5 & return=column
  • Perl usando complex_to_query:- columns:0=name&-columns:1=column&-limit=5&-where.-o.customer_id = 1 & - dónde.-o.services = schedule & return = column

JQuery y PHP son muy similares. Perl usando complex_to_query también es bastante similar a ellos. Pero ninguno mira exactamente lo mismo.

Author: Community, 2013-04-08

4 answers

URL-encode ( https://en.wikipedia.org/wiki/Percent-encoding ) su texto JSON y ponerlo en un solo parámetro de cadena de consulta. por ejemplo, si desea pasar {"val": 1}:

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

Tenga en cuenta que si su JSON se vuelve demasiado largo, entonces se encontrará con un problema de limitación de longitud de URL. En cuyo caso usaría POST con un cuerpo (sí, lo sé, enviar un POST cuando quieres buscar algo no es "puro" y no encaja bien en el paradigma REST, pero tampoco es tu dominio específico Lenguaje de consulta basado en JSON).

 41
Author: akonsu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-08 08:00:47

Otra opción podría ser node-querystring. También utiliza un esquema similar a los que has enumerado hasta ahora.

Está disponible tanto en npm como en bower, por lo que lo he estado usando.

 4
Author: wprl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-05 18:35:59

¿Qué tal si intentas enviarlos de la siguiente manera:

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

Lo intenté con un cliente de REST introduzca la descripción de la imagen aquí

Y en el lado del servidor (Ruby con Sinatra) comprobé los parámetros, me da exactamente lo que quieres. :-)

introduzca la descripción de la imagen aquí

 2
Author: Sagar Ranglani,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-20 13:56:18

No hay un único estándar para que JSON consulte la serialización de cadenas, así que hice una comparación de algunos serializadores JSON y los resultados son los siguientes:

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

El más corto entre ellos es URL Object Notation.

 2
Author: niutech,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-25 00:46:39