Я ищу способ обернуть API-интерфейсы вокруг функций по умолчанию в моих веб-приложениях на базе PHP, базах данных и CMS.
Я осмотрелся и нашел несколько «каркасных» рамок. В дополнение к ответам на мой вопрос есть Tonic , REST Framework, который мне нравится, потому что он очень легкий.
Мне нравится REST лучше всего за его простоту, и я хотел бы создать архитектуру API на его основе. Я пытаюсь разобраться с основными принципами и еще не до конца понял. Поэтому ряд вопросов.
1. Я правильно понимаю?
Скажем, у меня есть ресурс "пользователи". Я мог бы установить несколько URI, например, так:
/api/users when called with GET, lists users
/api/users when called with POST, creates user record
/api/users/1 when called with GET, shows user record
when called with PUT, updates user record
when called with DELETE, deletes user record
это правильное представление архитектуры RESTful до сих пор?
2. Мне нужно больше глаголов
Создать, обновить и удалить может быть достаточно в теории, но на практике мне понадобится гораздо больше глаголов. Я понимаю, что это вещи, которые могут быть встроены в запрос на обновление, но это конкретные действия, которые могут иметь определенные коды возврата, и я бы не хотел бросать их всех в одно действие.
Вот некоторые примеры, которые приходят на ум в пользовательском примере:
activate_login
deactivate_login
change_password
add_credit
Как бы я выразил действия, такие как в архитектуре RESTful URL?
Мой инстинкт должен был бы сделать вызов GET к URL, как
/api/users/1/activate_login
и ожидать код состояния обратно.
Это отличается от идеи использования HTTP-глаголов. Что вы думаете?
3. Как вернуть сообщения об ошибках и коды
Большая часть красоты REST связана с использованием стандартных методов HTTP. При ошибке я выдаю заголовок с кодом ошибки 3xx, 4xx или 5xx. Для подробного описания ошибки я могу использовать тело (правильно?). Все идет нормально. Но как можно было бы передать собственный код ошибки , более подробно описывающий, что пошло не так (например, «не удалось подключиться к базе данных» или «неверный вход в базу данных»)? Если я добавлю его в тело вместе с сообщением, мне придется потом разобрать его. Есть ли стандартный заголовок для такого рода вещей?
4. Как сделать аутентификацию
- Как будет выглядеть аутентификация на основе ключа API в соответствии с принципами REST?
- Есть ли сильные стороны против использования сессий при аутентификации клиента REST, кроме того, что это явное нарушение принципа REST? :) (шутка здесь только наполовину, аутентификация на основе сеанса будет хорошо сочетаться с моей существующей инфраструктурой.)
источник
Ответы:
Я заметил этот вопрос на пару дней позже, но я чувствую, что могу добавить немного понимания. Я надеюсь, что это может быть полезно для вашего RESTful предприятия.
Пункт 1: я правильно понимаю?
Вы правильно поняли. Это правильное представление архитектуры RESTful. Вы можете найти следующую матрицу из Википедии очень полезной для определения ваших существительных и глаголов:
При работе с Collection URI, например:
http://example.com/resources/
ПОЛУЧИТЬ : список членов коллекции, вместе с их URI членов для дальнейшей навигации. Например, список всех автомобилей на продажу.
PUT : значение, определенное как «заменить всю коллекцию другой коллекцией».
POST : создайте новую запись в коллекции, в которой идентификатор автоматически присваивается коллекцией. Созданный идентификатор обычно включается как часть данных, возвращаемых этой операцией.
DELETE : значение, определенное как «удалить всю коллекцию».
При работе с членом URI, как:
http://example.com/resources/7HOU57Y
GET : получить представление адресованного члена коллекции, выраженное в соответствующем типе MIME.
PUT : обновить указанный элемент коллекции или создать его с указанным идентификатором.
POST : рассматривает адресуемый член как коллекцию самостоятельно и создает нового подчиненного.
УДАЛИТЬ : Удалить указанного члена коллекции.
Пункт 2: мне нужно больше глаголов
В общем, когда вы думаете, что вам нужно больше глаголов, это может фактически означать, что ваши ресурсы должны быть переопределены. Помните, что в REST вы всегда действуете над ресурсом или набором ресурсов. То, что вы выбираете в качестве ресурса, очень важно для вашего определения API.
Активировать / деактивировать вход в систему : если вы создаете новый сеанс, вы можете рассмотреть «сеанс» как ресурс. Чтобы создать новый сеанс, используйте POST для
http://example.com/sessions/
с учетными данными в теле. Чтобы истечь, используйте PUT или DELETE (возможно, в зависимости от того, хотите ли вы сохранить историю сеансов)http://example.com/sessions/SESSION_ID
.Изменить пароль: на этот раз ресурс «пользователь». Вам потребуется PUT
http://example.com/users/USER_ID
со старыми и новыми паролями в теле. Вы действуете на «пользовательском» ресурсе, а изменение пароля - это просто запрос на обновление. Это очень похоже на оператор UPDATE в реляционной базе данных.Это противоречит основному принципу REST: правильному использованию глаголов HTTP. Любой запрос GET никогда не должен оставлять никаких побочных эффектов.
Например, запрос GET никогда не должен создавать сеанс в базе данных, возвращать cookie с новым идентификатором сеанса или оставлять какие-либо остатки на сервере. Глагол GET похож на оператор SELECT в ядре базы данных. Помните, что ответ на любой запрос с глаголом GET должен быть доступен для кэширования при запросе с теми же параметрами, как и при запросе статической веб-страницы.
Пункт 3: Как вернуть сообщения об ошибках и коды
Рассматривайте коды состояния HTTP 4xx или 5xx как категории ошибок. Вы можете разработать ошибку в теле.
Не удалось подключиться к базе данных: / Неправильный вход в базу данных : как правило, вы должны использовать 500 ошибок для этих типов ошибок. Это ошибка на стороне сервера. Клиент не сделал ничего плохого. 500 ошибок обычно считаются «повторяющимися». т. е. клиент может повторить тот же самый точный запрос и ожидать, что он будет успешным после устранения проблем сервера. Укажите детали в теле, чтобы клиент мог предоставить нам некоторый контекст для нас, людей.
Другой категорией ошибок будет семейство 4xx, которое в целом указывает на то, что клиент сделал что-то не так. В частности, эта категория ошибок обычно указывает клиенту, что нет необходимости повторять запрос, как он есть, потому что он будет продолжать сбой постоянно. т.е. клиент должен что-то изменить, прежде чем повторить этот запрос. Например, ошибки «Ресурс не найден» (HTTP 404) или «Неверный запрос» (HTTP 400) попадают в эту категорию.
Пункт 4: Как сделать аутентификацию
Как указано в пункте 1, вместо аутентификации пользователя вы можете подумать о создании сеанса. Вам будет возвращен новый «идентификатор сеанса» вместе с соответствующим кодом состояния HTTP (200: доступ разрешен или 403: доступ запрещен).
Затем вы спросите свой сервер RESTful: «Можете ли вы ПОЛУЧИТЬ мне ресурс для этого идентификатора сеанса?».
Режим аутентификации отсутствует - REST не имеет состояния: вы создаете сеанс, просите сервер предоставить вам ресурсы, используя этот идентификатор сеанса в качестве параметра, и при выходе из системы вы удаляете или истекаете сеанс.
источник
PUT
вероятно, неправильно использовали пароль для изменения пароля;PUT
требуется весь ресурс, поэтому вам нужно будет отправить все пользовательские атрибуты, чтобы соответствовать HTTP (и, следовательно, HATEOAS REST). Скорее, чтобы просто изменить пароль, нужно использоватьPATCH
илиPOST
.Проще говоря, вы делаете это полностью назад.
Вы не должны подходить к этому из того, какие URL вы должны использовать. URL-адреса будут фактически «бесплатными», как только вы определились с тем, какие ресурсы необходимы для вашей системы и как вы будете представлять эти ресурсы, а также взаимодействие между ресурсами и состоянием приложения.
Цитировать Роя Филдинга
Люди всегда начинают с URI и думают, что это решение, а затем они, как правило, упускают ключевую концепцию в архитектуре REST, в частности, как указано выше: «Ошибка здесь подразумевает, что внеполосная информация управляет взаимодействием, а не гипертекстом. "
Если честно, многие видят кучу URI и некоторые GET, PUT и POST и думают, что REST - это легко. ОТДЫХ не легко. RPC через HTTP - это просто, перемещение больших объемов данных назад и вперед по прокси через полезные нагрузки HTTP очень просто. Отдых, однако, выходит за рамки этого. REST не зависит от протокола. HTTP просто очень популярен и подходит для систем REST.
REST живет в типах носителей, их определениях и в том, как приложение управляет действиями, доступными для этих ресурсов через гипертекст (ссылки, эффективно).
Существуют разные взгляды на типы носителей в системах REST. Некоторые предпочитают полезную нагрузку, специфичную для приложения, в то время как другие предпочитают возвышение существующих типов мультимедиа в роли, подходящие для приложения. Например, с одной стороны, у вас есть конкретные схемы XML, разработанные для вашего приложения, в отличие от использования чего-то вроде XHTML в качестве вашего представления, возможно, с помощью микроформатов и других механизмов.
Я думаю, что оба подхода имеют свое место: XHTML очень хорошо работает в сценариях, которые перекрывают как управляемую человеком, так и управляемую машиной сеть, тогда как первые, более конкретные типы данных, которые я чувствую лучше, облегчают взаимодействие между машинами. Я считаю, что подъем товарных форматов может сделать переговоры о контенте потенциально трудными. «application / xml + yourresource» гораздо более специфичен как тип носителя, чем «application / xhtml + xml», поскольку последний может применяться ко многим полезным нагрузкам, которые могут или не могут быть чем-то, что на самом деле интересует клиент машины, и не может определить без самоанализа.
Тем не менее, XHTML работает очень хорошо (очевидно) в человеческой сети, где веб-браузеры и рендеринг очень важны.
Ваша заявка поможет вам в принятии таких решений.
Частью процесса проектирования системы REST является обнаружение первоклассных ресурсов в вашей системе, а также производных ресурсов поддержки, необходимых для поддержки операций с первичными ресурсами. Как только ресурсы обнаружены, тогда представление этих ресурсов, а также диаграммы состояний, показывающие поток ресурсов через гипертекст в представлениях, являются следующей задачей.
Напомним, что каждое представление ресурса в гипертекстовой системе объединяет как фактическое представление ресурса, так и переходы состояний, доступные для ресурса. Рассмотрим каждый ресурс как узел в графе, со ссылками, являющимися линиями, выходящими из этого узла в другие состояния. Эти ссылки информируют клиентов не только о том, что можно сделать, но и о том, что для них требуется (так как хорошая ссылка сочетает в себе URI и требуемый тип носителя).
Например, вы можете иметь:
Ваша документация расскажет о поле rel, названном «users», и о типе носителя «application / xml + youruser».
Эти ссылки могут показаться излишними, все они в основном разговаривают с одним и тем же URI. Но это не так.
Это связано с тем, что для отношения «пользователи» эта ссылка говорит о коллекции пользователей, и вы можете использовать унифицированный интерфейс для работы с коллекцией (GET для получения всех из них, DELETE для удаления всех из них и т. Д.)
Если вы отправляете POST по этому URL, вам нужно будет передать документ «application / xml + usercollection», который, вероятно, будет содержать только один экземпляр пользователя в документе, так что вы можете добавить пользователя или, возможно, добавить несколько в один раз. Возможно, ваша документация предполагает, что вы можете просто передать один тип пользователя вместо коллекции.
Вы можете увидеть, что требуется приложению для выполнения поиска, как определено ссылкой «поиск» и ее медиатипом. Документация по поисковому типу мультимедиа расскажет вам, как это ведет себя, и что ожидать в результате.
Вывод здесь, однако, заключается в том, что сами URI в основном не важны. Приложение контролирует URI, а не клиентов. Помимо нескольких «точек входа», ваши клиенты должны полагаться на URI, предоставленные приложением для своей работы.
Клиент должен знать, как манипулировать и интерпретировать типы медиа, но ему не нужно заботиться о том, куда он идет.
Эти две ссылки семантически идентичны в глазах клиентов:
Итак, сосредоточьтесь на своих ресурсах. Сосредоточьтесь на их переходах состояний в приложении и на том, как это лучше всего достигается.
источник
ре 1 : Это выглядит хорошо до сих пор. Не забудьте вернуть URI вновь созданного пользователя в заголовке «Location:» как часть ответа на POST вместе с кодом состояния «201 Created».
Re 2Активация через GET - плохая идея, и включение глагола в URI - запах дизайна. Вы можете рассмотреть вопрос о возвращении формы на GET. В веб-приложении это будет HTML-форма с кнопкой отправки; в случае использования API вы можете вернуть представление, содержащее URI для PUT, чтобы активировать учетную запись. Конечно, вы также можете включить этот URI в ответ на POST для / users. Использование PUT гарантирует, что ваш запрос идемпотентен, то есть его можно безопасно отправить снова, если клиент не уверен в успехе. В общем, подумайте о том, в какие ресурсы вы можете превратить свои глаголы (своего рода «обозначение глаголов»). Спросите себя, с каким методом ваши конкретные действия наиболее тесно связаны. Например, change_password -> PUT; деактивировать -> возможно УДАЛИТЬ; add_credit -> возможно POST или PUT.
3. Не изобретайте новые коды состояния, если только вы не уверены, что они настолько универсальны, что заслуживают стандартизации во всем мире. Старайтесь использовать наиболее подходящий код состояния (читайте обо всех из них в RFC 2616). Включите дополнительную информацию в тело ответа. Если вы действительно уверены, что хотите изобрести новый код состояния, подумайте еще раз; если вы все еще верите в это, убедитесь, что вы выбрали хотя бы правильную категорию (1xx -> OK, 2xx -> информационное, 3xx -> перенаправление; 4xx-> ошибка клиента, 5xx -> ошибка сервера). Я упоминал, что изобретать новые коды статуса - плохая идея?
4. Если возможно, используйте встроенную в HTTP инфраструктуру аутентификации. Проверьте, как Google выполняет аутентификацию в GData. В общем, не помещайте ключи API в ваши URI. Старайтесь избегать сеансов для повышения масштабируемости и поддержки кэширования - если ответ на запрос отличается из-за чего-то, что произошло раньше, вы обычно привязываете себя к конкретному экземпляру процесса сервера. Гораздо лучше превратить состояние сеанса либо в состояние клиента (например, сделать его частью последующих запросов), либо сделать его явным, превратив его в состояние (сервера) ресурса, то есть присвоить ему собственный URI.
источник
1. У вас есть правильное представление о том, как проектировать свои ресурсы, ИМХО. Я бы не стал ничего менять.
2. Вместо того, чтобы пытаться расширить HTTP с помощью большего количества глаголов, рассмотрите, к чему могут быть сокращены ваши предложенные глаголы, с точки зрения основных методов и ресурсов HTTP. Например, вместо
activate_login
глагола вы можете настроить такие ресурсы, как:/api/users/1/login/active
который является простым логическим значением. Чтобы активировать логин, простоPUT
документ там, который говорит «true» или 1 или что-то еще. Для деактивацииPUT
там есть пустой документ, в котором указано 0 или false.Точно так же, чтобы изменить или установить пароли, просто сделайте
PUT
s для/api/users/1/password
.Всякий раз, когда вам нужно что-то добавить (например, кредит), думать с точки зрения
POST
с. Например, вы можете сделатьPOST
для ресурса, например,/api/users/1/credits
с телом, содержащим количество кредитов для добавления. APUT
на том же ресурсе можно использовать для перезаписи значения, а не для добавления. АPOST
с отрицательным числом в теле вычтут и тд.3. Я бы настоятельно рекомендовал не расширять базовые коды состояния HTTP. Если вы не можете найти тот, который точно соответствует вашей ситуации, выберите ближайший и поместите детали ошибки в теле ответа. Также помните, что HTTP-заголовки являются расширяемыми; Ваше приложение может определить все пользовательские заголовки, которые вам нравятся. Например, одно приложение, над которым я работал, могло возвращать
404 Not Found
при нескольких обстоятельствах. Вместо того, чтобы заставлять клиента анализировать тело ответа по этой причине, мы просто добавили новый заголовокX-Status-Extended
, который содержал наши собственные расширения кода состояния. Таким образом, вы можете увидеть ответ вроде:Таким образом, HTTP-клиент, такой как веб-браузер, по-прежнему будет знать, что делать с обычным кодом 404, а более сложный HTTP-клиент может посмотреть в
X-Status-Extended
заголовке более конкретную информацию.4. Для аутентификации я рекомендую использовать HTTP-аутентификацию, если можете. Но IMHO, нет ничего плохого в использовании аутентификации на основе файлов cookie, если это проще для вас.
источник
Основы ОТДЫХА
REST имеют единое интерфейсное ограничение, которое гласит, что REST-клиент должен полагаться на стандарты, а не на конкретные прикладные детали фактической службы REST, поэтому REST-клиент не сломается при незначительных изменениях и, вероятно, будет использоваться повторно.
Таким образом, существует контракт между клиентом REST и сервисом REST. Если вы используете HTTP в качестве базового протокола, то в контракт входят следующие стандарты:
REST имеет ограничение без сохранения состояния, которое объявляет, что связь между службой REST и клиентом должна быть без сохранения состояния. Это означает, что служба REST не может поддерживать состояния клиента, поэтому у вас не может быть хранилища сеансов на стороне сервера. Вы должны аутентифицировать каждый запрос. Так, например, базовая аутентификация HTTP (часть стандарта HTTP) в порядке, поскольку она отправляет имя пользователя и пароль при каждом запросе.
Ответить на ваши вопросы
Да, это может быть.
Следует отметить, что клиенты не заботятся о структуре IRI, они заботятся о семантике, потому что они следуют по ссылкам, имеющим атрибуты отношений ссылок или связанных данных (RDF).
Единственное, что важно в IRI, это то, что один IRI должен идентифицировать только один ресурс. Разрешено одному ресурсу, например пользователю, иметь много разных IRI.
Это довольно просто, почему мы используем такие хорошие IRI, как
/users/123/password
; гораздо проще написать логику маршрутизации на сервере, когда вы понимаете IRI, просто читая его.У вас есть больше глаголов, таких как PUT, PATCH, OPTIONS и даже больше, но вам не нужно больше их ... Вместо того, чтобы добавлять новые глаголы, вы должны научиться добавлять новые ресурсы.
activate_login -> PUT /login/active true deactivate_login -> PUT /login/active false change_password -> PUT /user/xy/password "newpass" add_credit -> POST /credit/raise {details: {}}
(Вход в систему не имеет смысла с точки зрения REST из-за ограничения без сохранения состояния.)
Ваши пользователи не заботятся о том, почему проблема существует. Они хотят знать только, есть ли успех или ошибка, и, возможно, сообщение об ошибке, которое они могут понять, например: «Извините, но мы не смогли сохранить ваше сообщение.» И т. Д ...
Заголовки статуса HTTP - ваши стандартные заголовки. Все остальное должно быть в теле, я думаю. Одного заголовка недостаточно для описания, например, подробных многоязычных сообщений об ошибках.
Ограничение без сохранения состояния (наряду с ограничениями на кэш и многоуровневую систему) обеспечивает хорошее масштабирование службы. Вы, конечно, не хотите поддерживать миллионы сеансов на сервере, когда вы можете сделать то же самое на клиентах ...
Сторонний клиент получает токен доступа, если пользователь предоставляет ему доступ с помощью основного клиента. После этого сторонний клиент отправляет токен доступа при каждом запросе. Существуют более сложные решения, например, вы можете подписать каждый запрос и т. Д. Для получения более подробной информации обратитесь к руководству OAuth.
Сопутствующая литература
Диссертация Роя Томаса Филдинга (автор REST)
2000, Калифорнийский университет, Ирвин
Диссертация Маркуса Ланталера (соавтор JSON-LD и автор Hydra)
2014, Технологический университет Граца, Австрия
источник
Для приведенных вами примеров я бы использовал следующее:
activate_login
POST /users/1/activation
deactivate_login
DELETE /users/1/activation
изменить пароль
PUT /passwords
(предполагается, что пользователь аутентифицирован)add_credit
POST /credits
(предполагается, что пользователь аутентифицирован)Для ошибок вы должны вернуть ошибку в теле в формате, в котором вы получили запрос, поэтому, если вы получите:
DELETE /users/1.xml
Вы отправили бы ответ обратно в XML, то же самое было бы верно для JSON и т.д ...
Для аутентификации вы должны использовать http аутентификацию.
источник
create
как часть URI (помните, что URI должны быть существительными, а методы HTTP должны быть глаголами, которые работают с этими существительными.) Вместо этого у меня был бы такой ресурс,/users/1/active
который может быть простым логическим, и это может быть установите PUTting 1 или 0 для этого ресурса.activation
URI, если вы не будете явно манипулировать ресурсом и управлять им по имени/users/1/activation
. Что делает GET на это? Что делает PUT? Мне точно кажется, что вы глаголите URI. Кроме того, что касается согласования типа контента, его также лучше всего не указывать в URI и вставлять в заголовки, напримерAccept
.источник
Я хотел бы предложить (в качестве первого прохода), что
PUT
следует использовать только для обновления существующих объектов.POST
следует использовать для создания новых. т.е.не чувствует себя хорошо для меня. Однако остальная часть вашего первого раздела (использование глагола) выглядит логично.
источник
Подробно, но скопировано из спецификации метода HTTP 1.1 по адресу http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
9,3 ПОЛУЧИТЬ
Метод GET означает получение любой информации (в форме объекта), идентифицируемой посредством Request-URI. Если Request-URI ссылается на процесс создания данных, то именно полученные данные должны быть возвращены в качестве объекта в ответе, а не исходный текст процесса, если только этот текст не является выходом процесса.
Семантика метода GET изменяется на «условное GET», если сообщение запроса включает в себя поле заголовка If-Modified-Since, If-Unmodified-Since, If-Match, If-None-Match или If-Range. Условный метод GET запрашивает, чтобы объект передавался только при обстоятельствах, описанных в поле (ах) условного заголовка. Условный метод GET предназначен для уменьшения ненужного использования сети, позволяя обновлять кэшированные объекты без необходимости многократных запросов или передачи данных, уже хранящихся у клиента.
Семантика метода GET изменяется на «частичное GET», если сообщение запроса включает поле заголовка Range. Частичное GET запрашивает, чтобы была передана только часть объекта, как описано в разделе 14.35. Метод частичного GET предназначен для уменьшения ненужного использования сети, позволяя завершить частично извлеченные объекты без передачи данных, уже сохраненных клиентом.
Ответ на GET-запрос кэшируется тогда и только тогда, когда он соответствует требованиям для HTTP-кэширования, описанным в разделе 13.
См. Раздел 15.1.3 для соображений безопасности при использовании для форм.
9,5 ПОСТ
Метод POST используется для запроса, чтобы исходный сервер принял объект, заключенный в запросе, в качестве нового подчиненного ресурса, идентифицируемого Request-URI в строке запроса. POST разработан для того, чтобы унифицированный метод мог выполнять следующие функции:
Фактическая функция, выполняемая методом POST, определяется сервером и обычно зависит от Request-URI. Размещаемая сущность подчиняется этому URI так же, как файл подчиняется каталогу, в котором он находится, новостная статья подчиняется группе новостей, в которой она размещена, или запись подчиняется базе данных.
Действие, выполняемое методом POST, может не привести к ресурсу, который может быть идентифицирован с помощью URI. В этом случае либо 200 (ОК), либо 204 (Нет содержимого) является подходящим статусом ответа, в зависимости от того, включает ли ответ объект, который описывает результат.
Если ресурс был создан на исходном сервере, ответ ДОЛЖЕН быть 201 (Создан) и содержать объект, который описывает состояние запроса и ссылается на новый ресурс, и заголовок Location (см. Раздел 14.30).
Ответы на этот метод не могут быть кэшированы, если ответ не включает в себя соответствующие поля заголовка Cache-Control или Expires. Однако ответ 303 (см. «Другое») можно использовать для того, чтобы указать пользовательскому агенту извлечь кэшируемый ресурс.
POST-запросы ДОЛЖНЫ соответствовать требованиям к передаче сообщений, изложенным в разделе 8.2.
См. Раздел 15.1.3 для соображений безопасности.
9,6 ставок
Метод PUT запрашивает, чтобы вложенный объект был сохранен под предоставленным Request-URI. Если Request-URI ссылается на уже существующий ресурс, вложенный объект СЛЕДУЕТ рассматривать как модифицированную версию, находящуюся на исходном сервере. Если Request-URI не указывает на существующий ресурс, и этот URI может быть определен как новый ресурс запрашивающим пользовательским агентом, сервер происхождения может создать ресурс с этим URI. Если новый ресурс создан, сервер происхождения ДОЛЖЕН проинформировать пользовательский агент через ответ 201 (Создано). Если существующий ресурс изменен, то должны быть отправлены коды ответа 200 (ОК) или 204 (Нет содержимого), чтобы указать успешное завершение запроса. Если ресурс не может быть создан или изменен с помощью Request-URI, ДОЛЖЕН быть дан соответствующий ответ об ошибке, отражающий природу проблемы. Получатель объекта НЕ ДОЛЖЕН игнорировать какие-либо заголовки Content- * (например, Content-Range), которые он не понимает или не реализует, и ДОЛЖЕН возвращать ответ 501 (Не реализовано) в таких случаях.
Если запрос проходит через кеш, а Request-URI идентифицирует один или несколько кешируемых в данный момент объектов, эти записи ДОЛЖНЫ рассматриваться как устаревшие. Ответы на этот метод не кешируются.
Принципиальное различие между запросами POST и PUT отражается в различном значении Request-URI. URI в запросе POST идентифицирует ресурс, который будет обрабатывать вложенный объект. Этот ресурс может быть процессом приема данных, шлюзом к другому протоколу или отдельным объектом, принимающим аннотации. Напротив, URI в запросе PUT идентифицирует объект, заключенный в запросе - пользовательский агент знает, для чего предназначен URI, и сервер НЕ ДОЛЖЕН пытаться применить запрос к какому-либо другому ресурсу. Если сервер желает, чтобы запрос был применен к другому URI,
он ДОЛЖЕН отправить ответ 301 (постоянно перемещен); Затем пользовательский агент МОЖЕТ принять собственное решение относительно того, следует ли перенаправить запрос.
Один ресурс МОЖЕТ быть идентифицирован многими различными URI. Например, статья может иметь URI для идентификации «текущей версии», которая отделена от URI, идентифицирующего каждую конкретную версию. В этом случае запрос PUT для общего URI может привести к тому, что исходный сервер определит несколько других URI.
HTTP / 1.1 не определяет, как метод PUT влияет на состояние исходного сервера.
Запросы PUT ДОЛЖНЫ соответствовать требованиям к передаче сообщений, изложенным в разделе 8.2.
Если иное не указано для конкретного заголовка объекта, заголовки объекта в запросе PUT ДОЛЖНЫ применяться к ресурсу, созданному или измененному PUT.
9.7 УДАЛИТЬ
Метод DELETE запрашивает, чтобы исходный сервер удалил ресурс, указанный в Request-URI. Этот метод МОЖЕТ быть отменен вмешательством человека (или другими средствами) на исходном сервере. Клиент не может быть гарантирован, что операция была выполнена, даже если код состояния, возвращенный с исходного сервера, указывает, что действие было успешно выполнено. Однако серверу НЕ СЛЕДУЕТ указывать успех, если только во время ответа он не намерен удалить ресурс или переместить его в недоступное место.
Успешный ответ ДОЛЖЕН быть 200 (ОК), если ответ включает в себя объект, описывающий состояние, 202 (Принят), если действие еще не было выполнено, или 204 (Нет содержимого), если действие было выполнено, но ответ не включает сущность.
Если запрос проходит через кеш, а Request-URI идентифицирует один или несколько кешируемых в данный момент объектов, эти записи ДОЛЖНЫ рассматриваться как устаревшие. Ответы на этот метод не кешируются.
источник
О кодах возврата REST: неправильно смешивать коды протокола HTTP и результаты REST.
Однако я видел много реализаций, смешивающих их, и многие разработчики могут не согласиться со мной.
Коды возврата HTTP связаны с
HTTP Request
самим собой. Вызов REST выполняется с использованием запроса протокола передачи гипертекста, и он работает на более низком уровне, чем сам вызванный метод REST. REST является концепцией / подходом, и его выходные данные являются бизнес / логическим результатом, в то время как код результата HTTP является транспортным .Например, возвращение «404 Не найдено» при вызове / users / вызывает путаницу, поскольку это может означать:
«403 Запрещено / Доступ запрещен» может означать:
И этот список может продолжаться с «500 Server error» (ошибка в HTTP-запросе Apache / Nginx или ошибка бизнес-ограничения в REST) или другими ошибками HTTP и т. Д.
Из кода трудно понять, что было причиной сбоя, HTTP (транспортный) сбой или REST (логический) сбой.
Если HTTP-запрос физически выполнен успешно, он всегда должен возвращать 200 кодов, независимо от того, найдены записи или нет. Потому что ресурс URI найден и обработан сервером http. Да, он может вернуть пустой набор. Можно ли получить пустую веб-страницу с 200 в результате http, верно?
Вместо этого вы можете вернуть 200 HTTP-код и просто JSON с пустым массивом / объектом или использовать флаг результата / успеха bool для информирования о состоянии выполненной операции.
Кроме того, некоторые интернет-провайдеры могут перехватить ваши запросы и вернуть вам http-код 404. Это не означает, что ваши данные не найдены, но что-то не так на транспортном уровне.
Из вики :
источник