Стандартизированный способ сериализации JSON для запроса строки?

Я пытаюсь построить успокоительный API и я борюсь за то, как сериализовать JSON данные к HTTP query string,

Существует ряд обязательных и необязательных аргументов, которые необходимо передать в запросе, например (представленных в виде объекта JSON ниже):

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

Мне нужно поддерживать различное количество разных клиентов, поэтому я ищу стандартизированный способ преобразования этого объекта json в строку запроса. Есть ли один, и как это выглядит?

Другая альтернатива - позволить пользователям просто передавать объект json в теле сообщения, но я прочитал, что этого следует избегать ( HTTP GET с телом запроса).

Какие-нибудь мысли?

Изменить для уточнения:

Ниже показано, как некоторые разные языки кодируют данный объект json:

  • jQuery с помощью $.param: -columns[]=name&-columns[]=column&-where[-or][customer_id]=1&-where[-or][services]= расписание &-limit=5&return= столбец
  • PHP с помощью http_build_query: -columns[0]=name&-columns[1]=column&-where[-or][customer_id]=1&-where[-or][services]= расписание &-limit=5&return= столбец
  • Perl с помощью URI::query_form: -columns= имя &-columns=column&-where=HASH(0x59d6eb8)&-limit=5&return=column
  • Perl с помощью complex_to_query: -columns:0= имя & -columns: 1 = column & -limit = 5 & -where.-or.customer_id = 1 & -where.-or.services = schedule & return = column

jQuery и PHP очень похожи. Perl, использующий complex_to_query, также очень похож на них. Но никто не выглядит точно так же.

5 ответов

Решение

URL-кодирование ( https://en.wikipedia.org/wiki/Percent-encoding) вашего текста JSON и помещение его в один параметр строки запроса. например, если вы хотите пройти {"val": 1}:

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

Обратите внимание, что если ваш JSON слишком длинный, вы столкнетесь с проблемой ограничения длины URL. В этом случае я бы использовал POST с телом (да, я знаю, отправив POST когда вы хотите получить что-то не "чистое" и не вписывающееся в парадигму REST, но и язык запросов, основанный на JSON для вашего домена).

Не существует единого стандарта для JSON для запроса сериализации строк, поэтому я сделал сравнение некоторых сериализаторов JSON и получил следующие результаты:

JSON:    {"_id":"5973782bdb9a930533b05cb2","isActive":true,"balance":"$1,446.35","age":32,"name":"Logan Keller","email":"logankeller@artiq.com","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:'logankeller@artiq.com',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:'logankeller@artiq.com',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=logankeller@artiq.com&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=logankeller@artiq.com&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

Самым коротким из них является объектная нотация URL.

Как насчет того, чтобы попытаться отправить их следующим образом:

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

Я пробовал с клиентом REST введите описание изображения здесь

И на стороне сервера (Ruby with Sinatra) я проверил параметры, они дают мне именно то, что вы хотите.:-)

введите описание изображения здесь

Другим вариантом может быть строка-нода-запрос. Он также использует схему, аналогичную тем, которые вы перечислили.

Это доступно в обоих npm а также bowerВот почему я использую его.

Хорошо работает для вложенных объектов.

Передача сложных объектов в качестве параметров запроса файла . В приведенном ниже примере это объект JSON для передачи в параметры запроса.

Внедрение объекта JSON в качестве параметров запроса:

      value = JSON.stringify(obj);

URLSearchParamsдля преобразования строки в объект, представляющий параметры поиска.toStringчтобы сохранить тип строки для добавления к URL-адресу:

      queryParams = new URLSearchParams(value).toString();

Передайте параметры запроса, используя литералы шаблона:

      url = `https://some-url.com?key=${queryParams}`;

Теперь будет содержать объект JSON в качестве параметров запроса под (определяемое пользователем имя)

ИзвлечениеJSONот :

Это предполагает, что у вас есть доступ к (какstringилиURLобъект)

      url_obj = new URL(url); (only if url is NOT a URL object, otherwise ignore this step)

Извлеките все параметры запроса вurl:

      queryParams = new URLSearchParams(url_obj.search);

Использоватьkeyдля извлечения конкретного значения:

      obj = JSON.parse(queryParams.get('key').slice(0, -1));

slice()используется для извлечения хвоста=в параметрах запроса, которые не требуются.

Здесьobjбудет тот же объект, который передается в параметрах запроса.

Я рекомендую попробовать эти шаги в веб-консоли, чтобы лучше понять.

Вы можете протестировать примеры JSON здесь: https://json.org/example.html

Другие вопросы по тегам