как разработать RESTful api для использования купона?

#rest #api-design #restful-url

#rest #api-дизайн #restful-url

Вопрос:

Я разрабатываю RESTful api для выкупа купона. Каждый купон можно использовать только один раз, после погашения купон действует дольше.

(POST) /coupons/{couponCode}/redeem

кажется, нарушает правила RESTful, поскольку redeem это глагол. могу ли я просто перейти redeem на redemption ? или я могу просто использовать

(POST) /coupons/{couponCode} ?

кстати, я не совсем уверен, зачем использовать POST вместо PATCH, это потому, что PATCH является идемпотентным, а POST — нет? Я имею в виду, что когда купон будет использован в первый раз, он будет помечен как redeemed в базе данных, но как только это будет сделано, тот же запрос больше не обновит это значение.

Ответ №1:

кажется, нарушает рекомендации RESTful, поскольку выкупить — это глагол

REST не волнует, какое написание вы используете для своих идентификаторов ресурсов.

Итак, все эти варианты хороши

 POST /coupons/{couponCode}/redeem
POST /coupons/{couponCode}
POST /{couponCode}/redeem
POST /i/am/a/banana
POST /4ccd2f6f-a81e-4b70-b45c-20ce9f8732b5
  

Соглашения о написании идентификаторов похожи на соглашения об именовании переменных; они существуют только для облегчения бремени людей и подчиняются локальному соглашению. Машинам все равно.

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

Я не совсем уверен, зачем использовать POST вместо PATCH, это из-за того, что PATCH является идемпотентным, а POST — нет?

Нет. Разница в том, что PATCH обещает, что полезная нагрузка является документом исправления, то есть представлением набора изменений в представлении ресурса «the», тогда как POST просто говорит «это сообщение, которое должно быть обработано ресурсом».

(Как оказалось, и POST, и PATCH не являются идемпотентными.)

Представьте хранилище документов, где документы имеют размер около одного терабайта. Возможно, вы захотите изменить один из этих документов. Естественный способ сделать это — GET создать текущее представление, внести свои изменения, а затем PUT вернуть свою версию документа обратно. Но если ваши изменения очень малы, то много потраченной впустую работы по переносу дублированных копий документа.

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

СООБЩЕНИЕ более общее — это небезопасное сообщение с телом, и это почти все, что оно обещает. Это тело может быть новым представлением ресурса или исправлением, которое будет применено к текущему представлению, или чем-то совершенно другим.

почему использование выкупа не нарушает REST? не должны быть только глаголы HTTP-методов?

Потому что REST — это архитектурный стиль, и в нем говорится, что идентификаторами ресурсов должны быть URL (RFC 1738) — хотя в наши дни это обычно понимается как URI (RFC 3986) — или URN (RFC 8141).

Если вы посмотрите на RFC 3986, я думаю, вы обнаружите, что слово «глагол» нигде не встречается в документе. Вы можете просмотреть правила ABNF для интерпретации URI, и там нигде нет ничего о глаголах.

REST не волнует — URI в своем основном варианте использования является просто непрозрачной последовательностью байтов, которые используются клиентом.

Например, попробуйте нажать на эту ссылку в вашем браузере, это работает?

https://www.dictionary.com/browse/stop

Тот факт, что «stop» является глаголом в английском языке, не влияет на его функцию.

Я также вижу, что некоторые рекомендации по дизайну RESTful предлагают не использовать глаголы

Да, в Интернете полно советов от людей, которые не понимают предмета, или которые понимают предмет, но не формулируют его четко, и так далее.

REST не предлагает применять какой-либо конкретный стиль оформления URI.

В REST идентификатор — это просто идентификатор, такой как UUID, хэш-подпись или суррогатный ключ. В контексте HTTP-сообщения это ничего не значит, это просто ключ кэша. Семантика сообщения исходит от метода, а не от целевого запроса.

 GET /A/post HTTP/1.1

POST /B/get HTTP/1.1

DELETE /C/put HTTP/1.1

PUT /D/patch HTTP/1.1
  

В этих строках запроса нет двусмысленности, первый токен — это метод, который определяет семантику, второй токен — это просто произвольный идентификатор. Машины будут получать их правильно каждый раз.

Рекомендуемый просмотр

Комментарии:

1. почему использование redeem не нарушает REST? не должны быть только методы HTTP с глаголами? Я также вижу, что некоторые рекомендации по дизайну RESTful предлагают не использовать глаголы, например opensource.zalando.com/restful-api-guidelines/#138

2. REST настаивает на единообразных интерфейсах. HTTP-глаголы обеспечивают это единообразие. Перемещение глаголов в URL нарушает это единообразие. Я полагаю, что можно было бы создать соглашение об URL-адресах и игнорировать HTTP-глаголы, но оно должно быть широко признано, чтобы быть полезным

Ответ №2:

Для вас было бы лучше использовать URL-маршрут, в котором вы предоставляете действие выкупа. Этот маршрут должен использовать HTTP-запрос POST, потому что вы измените ресурс на сервере и будете принимать в качестве параметра ваш код купона.

 (POST) /coupons/redeem/{couponCode}
  

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

также можно использовать http-ИСПРАВЛЕНИЕ или запрос PUT. По соглашению мы используем PATCH или PUT для обновления ресурса после его создания, чтобы изменить один из его атрибутов. Если вы хотите использовать запрос ИСПРАВЛЕНИЯ для обновления, скажем, купона, который вы уже создали, тогда вы можете определить маршрут URL без действия выкупа. Тело запроса будет содержать поля, которые необходимо обновить для объекта купона (например, статус с «ожидающий» на «погашенный»)

 (PATCH / PUT) /coupons/{couponCode}
  

Многие используют следующее соглашение:

 GET /objects (return list of objects)
GET /objects/id (return object)
PUT /objects/id (update object)
POST /objects (add object)
DELETE /objects/id (remove object)