web-dev-qa-db-ja.com

JSONをクエリ文字列にシリアル化する標準化された方法?

落ち着いたAPIを構築しようとしていますが、JSONデータをHTTP query stringにシリアル化する方法に苦労しています。

リクエストで渡す必要のある必須およびオプションの引数がいくつかあります(例:以下のJSONオブジェクトとして表されます):

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

さまざまなクライアントをサポートする必要があるため、このjsonオブジェクトをクエリ文字列に変換する標準化された方法を探しています。ありますか?それはどのように見えますか?

もう1つの方法は、ユーザーがメッセージ本文でjsonオブジェクトを渡すことだけを許可することですが、それを避けるべきだと読みました( HTTP GET with request body )。

何かご意見は?

説明のために編集:

上記の特定のjsonオブジェクトをいくつかの異なる言語でエンコードする方法をリストします。

  • $.paramを使用するjQuery:-columns [] = name&-columns [] = column&-where [-or] [customer_id] = 1&-where [-or] [services] = schedule&-limit = 5&return = column
  • http_build_queryを使用したPHP:-columns [0] = name&-columns [1] = column&-where [-or] [customer_id] = 1&-where [-or] [services] = schedule&-limit = 5&return = column
  • URI::query_formを使用したPerl:-columns = name&-columns = column&-where = HASH(0x59d6eb8)&-limit = 5&return = column
  • complex_to_queryを使用したPerl:-columns:0 = name&-columns:1 = column&-limit = 5&-where.-or.customer_id = 1&-where.-or.services = schedule&return = column

jQueryとPHPは非常に似ています。complex_to_queryを使用するPerlも非常に似ています。しかし、まったく同じに見えるものはありません。

50
Andreas

URL-encode( https://en.wikipedia.org/wiki/Percent-encoding )JSONテキストを1つのクエリ文字列パラメーターに入れます。たとえば、{"val": 1}を渡す場合:

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

JSONが長くなりすぎると、URLの長さ制限の問題が発生することに注意してください。その場合、POSTを本文で使用します(はい、知っています。何かを取得したいときにPOSTを送信することは「純粋」ではなく、RESTパラダイムですが、ドメイン固有のJSONベースのクエリ言語でもありません)。

49
akonsu

JSONが文字列のシリアル化を照会するための単一の標準はないため、 JSONシリアライザーの比較 を作成しました。結果は次のとおりです。

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

それらの中で最も短いのは RL Object Notation です。

6
niutech

次のように送信してみてください:

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

REST Client enter image description here

そして、サーバー側(Sinatraを使用したRuby)でパラメーターを確認しましたが、まさにあなたが望むものを与えてくれます。 :-)

enter image description here

4
Sagar Ranglani

別のオプションは node-querystring です。また、これまでにリストしたものと同様のスキームを使用します。

npmbowerの両方で利用できるため、これを使用しています。

4
wprl