Как создать URL-адрес REST без глаголов?

Я пытаюсь определить, как создавать спокойные URL-адреса. Я все для спокойного подхода использования URL-адресов с существительными, а не глаголы не понимают, как это сделать.

Мы создаем сервис для реализации финансового калькулятора. Калькулятор берет кучу параметров, которые мы будем загружать через CSV файл. Варианты использования:

  • Загрузить новые параметры
  • Получить последние параметры
  • Получить параметры для данной бизнес-даты
  • Сделать набор параметров активным
  • Подтвердить набор параметров

Я собираюсь, чтобы успокоительный подход состоял в том, чтобы иметь следующие URL-адреса типов:

/parameters
/parameters/12-23-2009

Вы можете получить первые три варианта использования:

  • POST, где вы включаете файл параметров в запрос post
  • GET первого URL
  • GET второго URL

Но как вы делаете 4-й и 5-й варианты использования без глагола? Вам не нужны URL-адреса, например:

/parameters/ID/activate
/parameters/ID/validate

??

Ответ 1

Возможно, что-то вроде:

PUT /parameters/activation HTTP/1.1
Content-Type: application/json; encoding=UTF-8
Content-Length: 18

{ "active": true }

Ответ 2

Общие принципы хорошего дизайна URI:

  • Не использовать параметры запроса для изменения состояния
  • Не использовать пути смешанного случая, если вы можете помочь; нижний регистр лучше
  • Не использовать расширения для реализации в ваших URI (.php,.py,.pl и т.д.)
  • Не не попадайте в RPC с вашими URI
  • Do максимально ограничить пространство URI
  • Сделайте короткие сегменты путей
  • Do предпочитают либо /resource, либо /resource/; создать 301 переадресацию с той, которую вы не используете.
  • Использовать параметры запроса для подвыбора ресурса; т.е. разбиение на страницы, поисковые запросы
  • Do переместите материал из URI, который должен находиться в заголовке HTTP или теге

(Примечание: я не сказал "RESTful URI design", URI по существу непрозрачны в REST.)

Общие принципы выбора метода HTTP:

  • Не используйте, чтобы использовать GET для изменения состояния; это отличный способ, чтобы Googlebot разрушил ваш день.
  • Не использовать PUT, если вы не обновляете весь ресурс
  • Не использовать PUT, если вы не можете законно сделать GET на том же URI
  • Не использовать POST для получения долговременной информации или возможного кэширования
  • Не выполнять операцию, которая не является idempotent с PUT
  • Do используйте GET как можно больше
  • Do использовать POST в предпочтении PUT при сомнении
  • Do используйте POST, когда вам нужно что-то делать с RPC-подобным
  • Do используйте PUT для классов больших или иерархических ресурсов
  • Do используйте DELETE вместо POST для удаления ресурсов.
  • Do используйте GET для таких вещей, как вычисления, если только ваш вход большой, и в этом случае используйте POST

Общие принципы проектирования веб-сервисов с HTTP:

  • Не помещать метаданные в тело ответа, который должен быть в заголовке
  • Не помещать метаданные в отдельный ресурс, если не включать его, создавая значительные служебные данные
  • Do используйте соответствующий код состояния
    • 201 Created после создания ресурса; ресурс должен существовать во время отправки ответа
    • 202 Accepted после успешного выполнения операции или создания ресурса асинхронно
    • 400 Bad Request, когда кто-то делает операцию над данными, которые явно фиктивными; для вашего приложения это может быть ошибка проверки; как правило, резервировать 500 для исключенных исключений.
    • 401 Unauthorized, когда кто-то обращается к вашему API либо без предоставления необходимого Authorization заголовка, либо когда учетные данные в Authorization недействительны; не используйте этот код ответа, если вы не ожидаете учетных данных через заголовок Authorization.
    • 403 Forbidden, когда кто-то обращается к вашему API способом, который может быть вредоносным, или если они не авторизованы
    • 405 Method Not Allowed, когда кто-то использует POST, когда они должны использовать PUT и т.д.
    • 413 Request Entity Too Large, когда кто-то пытается отправить вам неприемлемо большой файл
    • 418 I'm a teapot при попытке brew кофе с чайником
  • Do используйте кеширующие заголовки, когда можете
    • Заголовки
    • ETag хороши, когда вы можете легко уменьшить ресурс до хэш-значения
    • Last-Modified должен указать вам, что сохранение временной метки при обновлении ресурсов - хорошая идея.
    • Cache-Control и Expires должны быть предоставлены разумные значения
  • Сделайте все, что можно, чтобы удостовериться в заголовках кеширования в запросе (If-None-Modified, If-Modified-Since)
  • Do используйте перенаправления, когда они имеют смысл, но они должны быть редки для веб-службы.

Что касается вашего конкретного вопроса, POST следует использовать для # 4 и # 5. Эти операции подпадают под руководство "RPC-like" выше. Для # 5 помните, что POST не обязательно должен использовать Content-Type: application/x-www-form-urlencoded. Это также может быть просто полезной нагрузкой JSON или CSV.

Ответ 3

Всякий раз, когда вам нужен новый глагол, подумайте о том, чтобы превратить этот глагол в существительное. Например, включите "активировать" в "активации", а "проверить" в "проверки".

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

Каждый раз, когда предлагается ресурс, называемый "параметром", он должен посылать красные флаги в уме каждого члена команды проекта. "параметр" может буквально применяться к любому ресурсу; это не достаточно конкретно.

Что именно представляет "параметр"? Вероятно, множество разных вещей, каждая из которых должна иметь отдельный ресурс, посвященный этому.

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

Это те слова, вокруг которых вы должны разрабатывать свое приложение.

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

Я ничего не знаю о финансовом программном обеспечении, но если бы мне пришлось угадывать, я бы сказал, что некоторые ресурсы могут идти по таким именам, как "Отчет", "Платеж", "Перевод" и "Валюта".

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

Ответ 4

Дизайн ваших URL не имеет ничего общего с тем, является ли ваше приложение RESTful или нет. Поэтому фраза "RESTful URLs" - это чепуха.

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

Тем не менее, давайте перейдем к вашему вопросу: последние два случая не являются RESTful и не вписываются в какую-либо схему отдыха. Это то, что вы могли бы назвать RPC. Если вы серьезно относитесь к REST, вам придется заново продумать, как ваше приложение работает с нуля. Либо так, либо откажитесь от REST и просто сделайте свое приложение как приложение RPC.

Хммм, может быть, нет.

Идея заключается в том, что вы должны рассматривать все как ресурс, поэтому, когда у набора параметров есть URL, с которого вы можете ссылаться на него, вы просто добавляете:

GET [parametersurl]/validationresults

POST [paramatersurl]
body: {command:"activate"}

Но опять же, эта активирующая вещь - RPC, а не REST.

Ответ 5

Активировать и проверять требования - это ситуации, когда вы пытаетесь изменить состояние ресурса. Ничем не отличается то, что заказ "завершен" или какой-либо другой запрос "отправлен". Существует множество способов моделирования таких изменений состояния, но я часто обнаруживаю, что это часто делается для создания ресурсов сбора ресурсов из одного и того же состояния, а затем для перемещения ресурса между коллекциями, чтобы повлиять на состояние.

например. Создайте некоторые ресурсы, такие как

/ActiveParameters
/ValidatedParameters

Если вы хотите активировать набор параметров, добавьте этот набор в коллекцию ActiveParameters. Вы можете либо передать набор параметров в качестве тела сущности, либо передать URL-адрес в качестве параметра запроса, как показано ниже:

POST /ActiveParameters?parameter=/Parameters/{Id}

То же самое можно сделать с параметрами /ValidatedParameters. Если параметры недействительны, сервер может вернуть "Bad Request" в запрос о добавлении параметров в коллекцию проверенных параметров.

Ответ 6

Я бы предложил следующий мета-ресурс и методы.

Сделайте параметры активными и/или подтвердите их:

> PUT /parameters/<id>/meta HTTP/1.1
> Host: example.com
> Content-Type: application/json
> Connection: close
>
> {'active': true, 'require-valid': true}
>
< HTTP/1.1 200 OK
< Connection: close
<

Проверьте, являются ли параметры активными и действительными:

> GET /parameters/<id>/meta HTTP/1.1
> Host: example.com
> Connection: close
>
< HTTP/1.1 200 OK
< Content-Type: application/json
< Connection: close
<
< {
<     'active': true,
<     'require-valid': true,
<     'valid': {'status': false, 'reason': '...'}
< }
<

Ответ 7

Изменить: Действительно, URI предотвратил бы оставшиеся идемпотентные запросы GET.


Однако для проверки правильность использования кодов состояния HTTP для уведомления о действительности запроса (для создания нового или изменения существующего параметра) будет соответствовать модели Restful.

Отправляйтесь с кодом состояния 400 Bad Request, если представленные данные являются недопустимыми, и запрос должен быть изменен перед повторной отправкой (HTTP/1.1 Status коды).

Это зависит от проверки на время подачи, а не отсрочки, как в вашем случае использования. Другие ответы имеют подходящие решения для этого сценария.

Ответ 8

В среде REST каждый URL является уникальным ресурсом. Каковы ваши ресурсы? Финансовый калькулятор действительно не имеет никаких очевидных ресурсов. Вам нужно покопаться в том, что вы называете параметрами, и вытащить ресурсы. Например, календарь погашения кредита может быть ресурсом. URL-адрес календаря может включать дату начала, срок (в месяцах или годах), период (когда начисляются проценты), процентную ставку и начальный принцип. Со всеми этими значениями у вас есть определенный календарь платежей:

http://example.com/amort_cal/2009-10-20/30yrsfixed/monthly/5.00/200000

Теперь я не знаю, что вы рассчитываете, но ваша концепция списка параметров не выглядит RESTful. Как кто-то еще сказал, ваши требования звучат более XMLRPC. Если вы пытаетесь получить отдых, вам нужны существительные. Вычисления - это не существительные, а глаголы, которые действуют на существительные. Вы должны перевернуть его, чтобы вытащить существительные из ваших кальков.