Выразительный Web API

0. nbeliaev 22.04.20 13:00 Сейчас в теме
Теория разработки Web API с ожидаемым поведением, за который не будет стыдно за пределами мира 1С.

Перейти к публикации

Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. CyberCerber 576 27.04.20 17:34 Сейчас в теме
Полезная статья, спасибо!
Буквально месяц - два назад сам искал best practices, правила написания хорошего API.
Ты рассказал про общие методы: создание, изменение объекта...
А как правильно реализовать, например, поиск объектов по фильтрам? Это будет GET или POST? Что стоит делать параметрами url, а что помещать в тело запроса?
nekit_rdx; +1 Ответить
2. nbeliaev 27.04.20 17:43 Сейчас в теме
(1) Спасибо за отзыв )
В разделе Примеры конкретных URI есть инфо как реализовать поиск по фильтрам и как его не надо делать (если быть точным то вот это /products?brand=NoName&class=A).
3. CyberCerber 576 27.04.20 17:55 Сейчас в теме
(2) А если нужно передать фильтры по сложнее? Например, найти товары:
1. В списке категорий: Телефоны, Планшеты, Часы
2. Имя содержит "самое лучшее устройство *&^%$#* !"
3. Страна производства не равна Китай
4. nbeliaev 27.04.20 18:02 Сейчас в теме
(3) Я бы все делал через параметры запроса, они специально для этого и заточены. То есть так как это все же получение данных, то метод GET, а в нем тела нет. Другой вопрос, что может немного придется распарсить такие параметры уже на стороне сервера.
6. CyberCerber 576 27.04.20 22:06 Сейчас в теме
(4) В общем случае, фильтры могут быть представлены произвольным JSONом. Нормально передавать JSON параметром URLа?
7. nbeliaev 28.04.20 05:36 Сейчас в теме
(6) Скорей всего придется кодировать такую строку из за спец. символов в json. А нормально ли передавать или нет, точного ответа я не могу дать, не сталкивался ни разу. Но сам бы я подумал хорошо еще раз перед тем как использовать такой подход.
8. ltfriend 515 28.04.20 09:19 Сейчас в теме
(6) конечно, идеологически для возврата результатов поиска больше подходит GET. Вы данные получаете, а не добавляете, изменяете или удаляете. Но если вы используете сложные параметры (фильтры), то разумней сделать POST с JSON'ом в теле. Это не является криминалом. А общие рекомендации не являются обязательными к исполнению и вполне могут быть исключения. И не стоит забывать, что передавая кучу сложных параметров в URL вы можете превысить его максимально допустимую длину.
9. nbeliaev 28.04.20 09:23 Сейчас в теме
(8) Согласен, что это всего лишь рекомендации и про длину вы верно подметили. Все зависит от конкретного кейса. Поэтому я и написал, что надо подумать.
Но в общем случае все же GET предпочтительнее )
10. ltfriend 515 28.04.20 09:25 Сейчас в теме
(9) в общем случае конечно. Но бывают частные, в которых как раз и можно отойти от общих рекомендаций.
11. CyberCerber 576 28.04.20 09:57 Сейчас в теме
(8) Да, вот у меня поэтому и был вопрос, т.к. частенько я встречаю API, где получение данных проходит через POST, т.к. в теле передается полноценный JSON.
12. nomad_irk 48 28.04.20 10:07 Сейчас в теме
(11)ИМХО, тут работает такое же правило, как и везде: если параметров у процедуры/функции можно пересчитать по пальцам одной руки, то их МОЖНО запихать в строку запроса GET, если больше - делай полноценный POST с блэкджеком и прочей атрибуикой......
5. nicxxx 238 27.04.20 18:30 Сейчас в теме
(1) Посмотрите документацию по интерфейсу oData, который 1С предоставляет по-умолчанию. Там есть про фильтры.
13. bulpi 174 28.04.20 12:09 Сейчас в теме
Единственный ИМХО сомнительный совет в статье :
"Методы POST и PUT должны отдавать соответственно созданный и измененный объекты обратно."
А если он там на фиг не нужен, зачем его отдавать?
14. nbeliaev 28.04.20 12:26 Сейчас в теме
(13) Спасибо за проявленный интерес.
Отдавать нужно, чтобы клиент мог проверить какие-то ключевые поля (например те, которые считаются на сервере). То есть ему не нужно дергать сервис еще раз через GET чтобы получить созданные/обновленные атрибуты сущности.
16. malikov_pro 411 29.04.20 05:52 Сейчас в теме
(14) Зависит от варианта использования, если данные записаны некорректно, то это ошибка сервиса, о которой нужно сообщить клиенту.

У Вас указана структура метаданных, но она неудобна для обработки листенерами (предварительные проверки и аутентификация), мои наработки по теме https://infostart.ru/public/1131305/, буду рад разумной критике.

В статью можно добавить вариант обработки 404, потому что при if GET/{id} -> 404(POST) else (PUT/{id}) насоздавать дубликатов, а 404 может выдать и прокси. Вариант решения договоренность через документацию о формате тела ответа при ошибке.

С вопросом практики реализации имеет смысл связать вопрос документирования.
17. nbeliaev 29.04.20 07:33 Сейчас в теме
(16) Спасибо за комментарий.

аутентификация
- у нас есть Basic auth. Если этого не достаточно, то можно использовать токены в заголовках.

предварительные проверки
- про что именно вы говорите? Валидация запроса? Если да, то не упомянул этот момент в публкации, может есть смысл добавить.

404
- конечно нужно это делать и не только 404. В целом я упомянул про коды статусов, но расписывать не стал, так как нужен более конкретный пример для этого.
18. malikov_pro 411 29.04.20 07:57 Сейчас в теме
(17)
"Basic auth" реализованная на уровне платформы привязана к пользователям в конфигураторе это не всегда удобно, как и подсистема БСП внешних пользователей.
В своих проектах использую справочник внешних пользователей и листенером для всех запросов делаю проверку.

"Валидация запроса?" - в общем да, проще проверить перед тем как отправлять данные в общий модуль (контроллер по сути).


"более конкретный пример для этого." - пример типа ресурса(формат RAML) во вложении, в основном блоке используется:
/categories:
  type: collection-item
  description: Работа со справочником категории (группы номенклатуры в 1С)
  /{xml_id}:
      type: item


Можно совместно продумать и сделать описание/реализацию основных функций по работе с объектами для 1С, аналог https://infostart.ru/public/709325/ только для сервера.
Прикрепленные файлы:
item.type.raml
15. hardcodder2020 28.04.20 13:11 Сейчас в теме
Статья полезная, спасибо, автор!
19. Vortigaunt 82 03.05.20 18:16 Сейчас в теме
В модуле http-сервиса только логика работы с объектом HTTPRequest. Вся бизнес-логика должна быть вынесена в общий модуль. Так вы получите независимые слои приложения (с натяжкой сюда можно прикрутить термин MVC) и простоту тестирования бизнес-логики.

Эта рекомендация важна не только ради красоты. Как оказалось, 1С не проверяет синтаксис в модуле http-сервиса. И чем меньше там будет кода, тем меньше нервов потратишь при отладке.
20. Cyberhawk 120 10.06.20 09:06 Сейчас в теме
Хорошо бы для каждого примера из раздела
Примеры неправильных URI
дать пояснение, что и почему там неправильно
21. nbeliaev 10.06.20 13:14 Сейчас в теме
(20)
Спасибо за интерес к материалу.
/products/getAll - REST оперирует глаголами, которые предоставляют методы HTTP. Здесь мы изобрели "свой" глагол
/products/brand/NoName - Попробуйте представить что будет, если кроме brand будет еще хотя бы 5 параметров. Для этого есть параметры запроса, а не части пути.
/products/?action=put&id=0 - Практически аналогично с первым пунктом, только здесь глагол как параметр запроса.
/products/delete/?id=0 - Практически аналогично с первым пунктом, только здесь глагол как часть пути.
22. Cyberhawk 120 10.06.20 13:24 Сейчас в теме
(21) Я не для себя спрашивал :)
Неплохо бы добавить эти пояснения в саму публикацию.
Оставьте свое сообщение
Вопросы с вознаграждением