2009-10-24 10 views
271

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

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

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

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

/parameters 
/parameters/12-23-2009 

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

  1. POST, где вы включаете файл параметров в запросе пост
  2. GET первого URL
  3. GET второго URL

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

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

??

+3

Я предпочитаю PATCH вместо POST для частичного обновления. – user2016971

ответ

68

Может быть что-то вроде:

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

{ "active": true } 
+0

Хорошее предложение. Поскольку мы могли бы иметь несколько наборов параметров, нам понадобится что-то вроде POST/parameters/id/activation ... –

+1

'POST' ОК, если вам нужно выполнить« процедуру », например, проверять параметры каждый раз, когда вы отправляете запрос. Но когда вы изменяете (приложение) состояние ресурса, вы фактически ** обновляете ** существующий ресурс, а не создаете какой-то новый ресурс или отправляете запрос на обработку. –

+0

'POST' сродни вставке и обновлению, а' PUT' сродни только обновлению. – yfeldblum

0

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


Для проверки достоверности, однако, использование кодов статуса HTTP уведомить обоснованность запроса (создать новый или изменить параметр «» существующий) будет соответствовать успокоительной модели.

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

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

+0

URI должен быть идентификатором. Использование определенного URL-адреса не должно иметь побочных эффектов. Представьте, что прокси-сервер с этим сделает. – Breton

+2

или Google, если на то пошло. Однажды я прочитал рассказ о веб-магазине, в котором все их продукты были удалены google из-за такого рода идиотизма. – Breton

1

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

параметры активизируют и/или проверить их:

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

Эй, почему вы проголосовали за мой ответ? –

+0

Насколько я понимаю, речь идет о наименовании спокойных URL-адресов, а не о функциональности, не так ли? – poezn

+2

Вопрос, ограниченный «URL RESTful», является плохим и не должен отвечать. Вместо этого вопрос должен быть расширен, чтобы рассмотреть «ресурсы RESTful, связанные с ними методы и URL-адреса», - и ответил как таковой. – yfeldblum

11

Конструкцией ваши URL-адреса не имеют никакого отношения к тому, является ли ваше приложение RESTful или нет. Таким образом, фраза «RESTful URLS» является бессмысленной.

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

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

Hrmmm, возможно, нет.

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

получить [parametersurl]/validationresults

пост [paramatersurl]

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

но опять-таки, что активировать вещь RPC, не ОТДОХНУТЬ.

+0

Здесь вы указываете интересный момент. Можете ли вы подробнее рассказать о том, как подход RESTful для чего-то подобного? – poezn

+0

Я потратил немного времени на чтение ответов здесь, и я думаю, что справедливость может быть чем-то. он моделирует индивидуальные свойства объекта параметров как отдельные ресурсы и использует глагол PUT для замены содержимого этого свойства на этом ресурсе. Это моделирует состояние каждого объекта как совокупность ресурсов и модифицирует состояние как размещение или удаление или изменение ресурса. Что касается проверки - вам нужен только ресурс, который волшебным образом указывает, являются ли параметры действительными или нет, как указано выше в моем ответе. Это было бы хорошо, если у этого не было побочных эффектов. – Breton

+0

Разумеется, что то, что «Активировать», просто задает единственное свойство true. Если он должен что-то делать, то он все еще не RESTful, и я не уверен, как вы бы моделировали его RESTfully. – Breton

16

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

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

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

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

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

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

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

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

В этой части процесса разработки программного обеспечения есть множество хороших книг. Два, которые я могу порекомендовать, - Domain Driven Design и Analysis Patterns.

+3

+1 для "какие слова используют пользователи?" – jmucchiello

+1

Это действительно хороший момент. Легко пропустить, если вы находитесь в состоянии ума для обработки формальной логики и рассуждений. Не имеет значения, что X до тех пор, пока он правильно сочетается с другими частями. Человеческие факторы просто ускользают. – Breton

+1

Иногда мне представляется полезным преобразовать слова в «ресурс обработки», например «активатор» или «валидатор». Согласно RFC 2616 POST можно использовать для «Предоставление блока данных ... процессу обработки данных» –

0

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

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

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

+5

Я думаю, что немного глупо использовать косые черты здесь, что было бы неправильно с amort_cal? Date = 2009-10-20 & type = 30yrsfixed & period = month & rate = 5.0 & initialamount = 200000? REST не волнует, пока это ресурс. Однако URI spec * делает *. Как вы представляете себе относительные ссылки на работу с такой схемой? – Breton

+0

Тем не менее вы поднимаете хороший момент. Нужны ли эти «параметры» для хранения серверов? Если это всего лишь один расчет, почему бы просто не создать виртуальное пространство, где параметры находятся в URL-адресе. Пока вы не меняете внутреннее состояние, все должно быть хорошо. – Breton

+0

Какие относительные ссылки? Относительно чего? Нет ничего, что требовало бы, чтобы вы назвали свои параметры так, как вы заявляете. REST включает ресурсы, а не исполняемые файлы с параметрами. Кроме того, вы должны искать SEO и снова спрашивать, почему вы, возможно, не захотите использовать & foo = val & – jmucchiello

966

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

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

(Примечание: Я не сказал «RESTful дизайн URI», идентификаторы URI, по существу, непрозрачной в REST.)

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

  • Не когда-либо использовать GET для изменения состояния; это отличный способ, чтобы иметь Googlebot испортить ваш день
  • Не использовать PUT, если вы обновляете весь ресурс
  • Do не использовать PUT, если вы не можете законно сделать GET на том же URI
  • не использовать POST для получения информации, которая является долгоживущим, или что может быть разумным кэшировать
  • не выполнить операцию, которая не idempotent с PUT
  • ли использование GET для максимально
  • ли использовать POST в предпочтении к PUT, если сомневаетесь
  • ли использовать POST, когда вы должны сделать что-то, что чувствует RPC-как
  • Do использования PUT для классов ресурсов, которые больше или иерархической
  • ли использования DELETE в предпочтении к POST для удаления ресурсов
  • ли использовать 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 teapotwhen attempting to brew coffee with 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.

+146

+1 для «Я чайник» –

+37

Этот список DO и DO NOT * отлично * Kudos. – MikeSchinkel

+11

413 предназначен для размера запроса, который вы отправляете, чтобы вы могли вежливо отклонить кого-то, отправляющего вам гигабайты данных, часто в сочетании с 411, чтобы вы заставили людей рассказать вам, сколько отправляется. Для примера, приведенного против 413, я думаю, что 400 будет более подходящим ответом. –

6

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

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

/ActiveParameters 
/ValidatedParameters 

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

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

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