Как передать сложные запросы в REST?
-
22-08-2019 - |
Вопрос
Если я правильно понимаю, в стиле отдыха каждый запрос (то есть каждое действие над каждым ресурсом, которое не изменяет состояние ресурса) должен быть закодирован в строке запроса с использованием метода get вообще без тела.
Я прав?
Ну, у меня есть несколько приложений, которые взаимодействуют с базой данных через сообщение XML, которое обрабатывается компонентом Visual Basic 6.
сообщение для запроса примерно такое
<xml>
<service>account</service>
<resource>invoice</resource>
<action>query</action>
<parameters>
<page>1</page>
<page_len>10</page_len>
<order>date</order>
<fields>*</fields>
<conditions>
<date>2009-01-01..2009-01-31</date>
<customer_id>24</customer_id>
</conditions>
</parameters>
</xml>
Сейчас мы находимся в процессе перепроектирования наших XML-сообщений, и нам хотелось бы сделать это таким образом, чтобы их можно было легко сопоставить с интерфейсом RESTful.
В предыдущем примере нам нужны теги «условия», чтобы предотвратить конфликты между параметрами и условиями (т. е. что произойдет, если у меня есть поле с именем «заказ», «страница» или что-то в этом роде...
Мы подумали об отправке параметров с префиксом, что-то вроде
http://account/invoice/?_page=1&_page_len=10&_order=date&_fields=*&date=2009-01-01..2009-01-31&customer_id=24
и XML будет что-то вроде
[...]
<_order>date</_order>
<_fields>*</_fields>
<date>2009-01-01..2009-01-31</date>
<customer_id>24</customer_id>
[...]
Мы пытаемся определить действительно простой формат XML для операций crud, чтобы полученный XML можно было легко сопоставить с rest или JSON.
Как бы вы отобразили такой запрос в приложении для отдыха?Определен ли какой-то стандарт?или какая-то страница с образцами crud rest/XML/JSON?как насчет возврата ошибки или вложенных наборов данных?
Большое спасибо.
Решение
ИМХО, чтобы сделать вашу систему по-настоящему RESTful, вам необходимо переосмыслить все сообщения/запросы, которые вы будете отправлять.
Эта часть:
<conditions>
<date>2009-01-01..2009-01-31</date>
<customer_id>24</customer_id>
</conditions>
это самая сложная часть.Какие еще у вас условия?Много ли?Этот конкретный пример заставляет меня думать, что счета можно рассматривать как подресурс клиента.Когда я отдыхаю, я всегда пытаюсь идентифицировать ресурс в пути, и если запросу все еще нужны какие-либо параметры, я перемещаю их в строку запроса.Поэтому я бы написал что-то вроде этого:
GET /customers/24/invoices?start_date=2009-01-01&end_date=2009-01-31
Подумайте об отношениях между вашими ресурсами.Допустим, у нас есть тип ресурса Foo, связанный с типом ресурса Bar отношением -ко-многим.В этом случае вы можете спросить об этом отношении следующим образом: GET /foo/123/bar
и добавьте параметры строки запроса для ее фильтрации.Проблема начинается, когда вы хотите отфильтровать его таким образом, чтобы он включал отношения к другим ресурсам.ИМХО, это означает, что ваш дизайн ресурсов не совсем RESTful.
Другие советы
Вам нужно будет закодировать URL-адрес XML, чтобы иметь возможность передать его, но если вы преобразовали XML в json, вы можете передать эту строку, а затем json->xml или json->object для ее обработки.Это позволит вам передавать более сложные объекты.
Это не идеально, но работает.:)