Вопрос

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

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

  1. Загрузить новые параметры
  2. Получите последние параметры
  3. Получение параметров для заданной деловой даты
  4. Сделайте набор параметров активным
  5. Проверка набора параметров

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

/parameters
/parameters/12-23-2009

Вы могли бы реализовать первые три варианта использования с помощью:

  1. ОПУБЛИКУЙТЕ, где вы включаете файл параметров в запрос post
  2. ПОЛУЧЕНИЕ первого URL-адреса
  3. ПОЛУЧЕНИЕ второго URL-адреса

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

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

??

Это было полезно?

Решение

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

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

{ "active": true }

Другие советы

Общие принципы хорошего проектирования URI:

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

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

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

  • Не надо вы когда-нибудь использовали GET для изменения состояния;это отличный способ заставить робота Googlebot испортить вам день
  • Не надо используйте PUT, если только вы не обновляете весь ресурс целиком
  • Не надо используйте PUT, если вы также не можете законно выполнить GET для того же URI
  • Не надо используйте POST для извлечения информации, которая является долговременной или которую может быть разумно кэшировать
  • Не надо выполните операцию, которая не идемпотентный с помощью PUT
  • Делай используйте GET как можно чаще
  • Делай используйте POST в качестве предпочтения для РАЗМЕЩЕНИЯ, когда сомневаетесь
  • Делай используйте POST всякий раз, когда вам нужно сделать что-то, похожее на RPC
  • Делай используйте PUT для классов ресурсов, которые являются более крупными или иерархическими
  • Делай используйте "УДАЛИТЬ" вместо "ОПУБЛИКОВАТЬ", чтобы удалить ресурсы
  • Делай используйте GET для таких вещей, как вычисления, если только ваши входные данные не велики, в этом случае используйте POST

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

  • Не надо поместите метаданные в тело ответа, которые должны быть в заголовке
  • Не надо поместите метаданные в отдельный ресурс, если только их включение не приведет к значительным накладным расходам
  • Делай используйте соответствующий код состояния
    • 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 при попытке заварить кофе с помощью чайника
  • Делай используйте заголовки кэширования всякий раз, когда вы можете
    • ETag заголовки хороши, когда вы можете легко свести ресурс к хэш-значению
    • Last-Modified должен указать вам, что сохранение метки времени обновления ресурсов является хорошей идеей
    • Cache-Control и Expires должны быть даны разумные значения
  • Делай все, что вы можете для соблюдения кэширования заголовков в запросе (If-None-Modified, If-Modified-Since)
  • Делай используйте перенаправления, когда они имеют смысл, но для веб-службы они должны быть редкими

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

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

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

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

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

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

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

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

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

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

Дизайн ваших URL-адресов не имеет никакого отношения к тому, является ли ваше приложение RESTful или нет.таким образом, фраза "RESTful URLS" является бессмыслицей.

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

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

Хммм, может, и нет.

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

получить [parametersurl]/validationresults результаты проверки

сообщение [paramatersurl]

Тело:{команда:"активировать"}

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

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

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

/ActiveParameters
/ValidatedParameters

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

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

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

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

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

> 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': '...'}
< }
<

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

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

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

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


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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top