REST: Как поддержать создание-или-обновление и частичное обновление?(иначе PUT vs PATCH) - PullRequest
0 голосов
/ 23 сентября 2019

Мы разрабатываем WebAPI для нашего программного обеспечения для управления информацией о продуктах электронной коммерции.Мы хотим предоставить (среди многих других) две операции:

  1. Простая: разрешить пользователю добавлять / изменять информацию о существующем продукте:
    • не создавать новый продукт, если он не существует
    • не удаляйте информацию из существующего продукта, которая не была предоставлена ​​в этом запросе

По моему мнению, метод HTTP PATCH является правильным способом для обработки этого сценария(с помощью json-patch или json-merge-ptach) с таким URL-адресом: / products / {ID}

Сложнее: разрешить пользователю добавлять / изменять существующий продукт или создавать один
  • создавать продукт, если его нет в БД
  • не удалять информацию из существующего продукта, которая не была предоставлена ​​вэтот запрос (то же поведение, что и в первом случае)

Я борюсь за разработку конечной точки REST для этого второго варианта использования.У меня есть несколько вариантов, но ни один из них не подходит для меня в соответствии с принципами REST:

  • a) Добавить настраиваемый заголовок HTTP к конечной точке, предназначенной для первого случая (патча), чтобы позволить вызывающему абонентуконтроль "не найденного поведения", например.create-entity-when-not-существующие: true / false - но, по моему мнению, PATCH не следует использовать для создания ресурсов.

  • b) Разработка новой конечной точки с использованием PUT со специальным заголовком«сохранить-не-предоставленные-данные» - это, с другой стороны, нарушает для меня принципы PUT, поскольку PUT - это метод «создать или заменить», а не «создать или обновить»

  • c) СоздатьPATCH для / products URL (без {ID} в конце) - в этом случае мы обновляем всю коллекцию (ресурс) продуктов - поэтому, если продукт существует, мы можем обновить его или создать новый, если он не существует.

На данный момент c) решение выглядит хорошо для меня с одним исключением: если в будущем мы хотели бы поддерживать пакетные операции (для обоих вариантов использования: 1 и 2), мы хотели быиспользуйте / products URL, и он будет конфликтовать с URL из решения c)

Что вы думаете?У вас есть другие идеи?

1 Ответ

0 голосов
/ 23 сентября 2019

PUT и PATCH имеют различную семантику сообщений, но основной контекст («удаленная авторизация») одинаков.В обоих случаях запрос клиента: «Пожалуйста, сервер, сделайте так, чтобы ваше представление этого ресурса совпадало с моей локальной копией».

Например, я GET документ JSON с сервера.Я делаю локальные правки к нему.Теперь я хочу «сохранить» свои изменения на сервере.Если документ скромный по размеру, я мог бы просто отправить весь пересмотренный документ по сети.Если документ очень большой, а мои изменения скромные, то вместо этого я мог бы вместо этого отправить патч.

Если вы представляете себе использование HTTP для публикации изменений веб-страниц HTML на сервере, то у вас естьправильная система отсчета.Нет большой практической разницы между «пожалуйста, исправьте заголовок вашей копии документа» и «вот новая полная копия документа, с моим редактированием заголовка».Байты на диске будут одинаковыми в любом случае.

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

Ваш третий подход, основанный на изменении /products, потенциально хорош как для вашего индивидуума, так и для партии.Сервер получает новое представление /products (или документ исправления, описывающий изменения), решает, принимать ли изменения и, если да, вычисляет, что ему нужно сделать, с его собственной базой данных, чтобы все заработало.

Примечание:

Запрос PUT, примененный к целевому ресурсу, может иметь побочные эффекты для других ресурсов.

Спецификация HTTP относительно строга в отношении сообщения означает , но предлагает серверу много возможностей для поведения в ответ.

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