POST список предметов, используя REST - PullRequest
8 голосов
/ 19 ноября 2011

Я ищу соглашение о том, как сериализовать мои данные, когда у меня есть (длинный) список элементов, которые я хочу отправить на сервер.

Например, если у меня есть ресурс /users и я хотел бы добавить в него новое сообщение, я бы http-кодировал поля для нового пользователя и помещал его в тело запроса следующим образом: name=foo&age=20

Но если бы у меня был списокпользователей, вроде этого [{ name: 'foo', age: 20 }, { name: 'bar', age: 10 }], есть ли обычный способ размещения этого сообщения?

Я думаю name[0]=foo&age[0]=20&name[1]=bar&age[1]=10, но я не могу найти ничего, что могло бы его поддержать.Что веб-серверы обычно принимают / ожидают?

Ответы [ 2 ]

9 голосов
/ 19 ноября 2011

Быстрый вопрос, который может изменить мой ответ: отправляете ли вы POST непосредственно из HTML-формы или ожидаете чего-то более сложного (например, обработка javascript или даже не веб-клиент)

Если у вас достаточно сложный клиент, вы можете просто создать строку JSON и POST с типом содержимого application/json. Тогда любой ресурс, обрабатывающий POST, может использовать любое количество библиотек json для чтения опубликованной строки и обработки как есть.

Дальнейшее Рамблинг:

Какие рамки / языки вы используете для создания службы REST? Есть ли у них встроенные функции / соглашения, чтобы помочь вам?

Например, если вы используете JAX-RS для создания своего сервиса, есть встроенная аннотация @ FormParam , которую можно использовать для обработки опубликованных форм ... например: если вы опубликовали следующий с типом контента application/x-www-form-urlencoded: name=foo&age=20&name=bar&age=10

Вы можете получить параллельные списки на стороне службы с помощью:

@POST
@Consumes("application/x-www-form-urlencoded")
public void createUsers(@FormParam("name") List<String> name, @FormParam("age") List<String> age) {
    // Store your users
}

Но тогда вам придется столкнуться с вопросом: что, если один список короче / длиннее другого, как вы решите это? Что произойдет, если новое поле является обязательным или необязательным для создания списка пользователей? (Но, как я упоминал вначале, JSON-массив JSON-объектов мог бы решить эту проблему ... существует ряд библиотек, которые поддерживают автоматическую десериализацию JSON в JAX-RS, или есть также возможность создания собственного MessageBodyReader .

(Отказ от ответственности в следующем разделе: я не знаю rails, мой опыт больше в мире сервисов Java ... Я основываюсь на этом руководстве ). Похоже, что в Rails есть соглашение name[]=foo&name[]=bar для автоматической обработки опубликованных данных в массивах и аналогичное соглашение для заполнения структуры, такое как user[name]=foo&user[age]=20 ... Возможно, если вы находитесь на рельсах, есть какой-то способ использования / злоупотребления обоими этими особенности, чтобы получить желаемый результат?

Другие платформы и языки REST могут иметь свои собственные соглашения и функции:)

1 голос
/ 19 ноября 2011

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

name=theo&company[name]=acme

(эквивалент JSON будет {"name": "theo", "company": {"name": "acme"}})

Я не могу сказать, что видел, как приложение Rails отправляло массивы, но нет никаких причин, почему оно не будет работать (в худшем случае вы получите хеш со строковыми ключами).

PHP имеет другое соглашение, если вы хотите отправить массив, который вы делаете

names[]=alice&names[]=bob&names[]=steve

Но я не знаю, как вы делаете вложенные объекты таким образом.

Спецификация HTTP, или, если это спецификация URI, не уверенная, какой atm, на самом деле указывает, что, если вы передаете один и тот же аргумент несколько раз, вы получаете массив значений (вместо поведения последних побед большинства структур приложений). Это можно увидеть в документации API для Jetty, например: http://api.dpml.net/org/mortbay/jetty/6.1.5/org/mortbay/jetty/Request.html#getParameterValues(java.lang.String)

Однако большая часть этого относится к GET запросам, необязательно POST (но, возможно, application/x-url-encoded должен соответствовать тем же стандартам, что и GET).

Короче говоря, я не думаю, что для этого существует стандарт , тела POST - это что-то вроде территории дикого запада. Однако я думаю, что либо вы должны использовать JSON, потому что он создан для описания структур, а application/x-url-encoded нет, либо вам следует попытаться лучше представить структуру ваших данных, например:

users[0][name]=foo&users[0][age]=20&users[1][name]=bar&users[1][age]=10

У этого есть некоторый шанс, что он будет интерпретирован, например, приложением Rails из коробки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...