Я разрабатывал веб-приложение, а затем остановился, чтобы подумать о том, как мой api должен быть спроектирован как веб-сервис RESTful. На данный момент большая часть моего URI является общей и может применяться к различным веб-приложениям:
GET /logout // destroys session and redirects to /
GET /login // gets the webpage that has the login form
POST /login // authenticates credentials against database and either redirects home with a new session or redirects back to /login
GET /register // gets the webpage that has the registration form
POST /register // records the entered information into database as a new /user/xxx
GET /user/xxx // gets and renders current user data in a profile view
POST /user/xxx // updates new information about user
У меня такое чувство, что я делаю много неправильного здесь, после того, как тыкнул SO и Google.
Начиная с /logout
, возможно, так как я действительно не GET
ничего - может быть более подходящим для POST
запроса /logout
, уничтожить сеанс, а затем GET
перенаправить. И должен ли срок /logout
оставаться?
Как насчет /login
и /register
. Я мог бы изменить /register
на /registration
, но это не повлияет на то, как работает мой сервис, если у него есть более глубокие проблемы.
Теперь я замечаю, что никогда не показываю ресурс /user
. Возможно, это можно было бы использовать как-то. Например, возьмите пользователя myUser
:
foo.com/user/myUser
или
foo.com/user
Конечный пользователь не требует дополнительной многословности в URI. Однако какой из них более привлекателен визуально?
Я заметил некоторые другие вопросы здесь о SO об этом бизнесе REST, но я был бы очень признателен за некоторые рекомендации относительно того, что я здесь изложил, если это возможно.
Спасибо!
UPDATE:
Мне также хотелось бы получить некоторые мнения о:
/user/1
против
/user/myUserName
Одна вещь торчит, в частности, как не REST-ful: использование запроса GET для выхода из системы.
(из http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Safe_methods)
Некоторые методы (например, HEAD, GET, OPTIONS и TRACE) определяются как безопасные, что означает, что они предназначены только для извлечения информации и не должны изменять состояние сервера. Другими словами, они не должны иметь побочных эффектов, помимо относительно безвредных эффектов, таких как ведение журнала, кеширование, подача рекламных баннеров или увеличение веб-счетчика. [...]
[... H] andling [запросов GET] сервером никак не ограничивается технически. Поэтому небрежное или преднамеренное программирование может привести к нетривиальным изменениям на сервере. Это обескураживает, поскольку это может вызвать проблемы для веб-кеширования, поисковых систем и других автоматизированных агентов [...]
Что касается выхода из системы и перенаправления, вы можете отправить сообщение в свой логарифм URI, чтобы перенаправить перенаправление 303 на страницу после выхода.
http://en.wikipedia.org/wiki/Post/Redirect/Get
http://en.wikipedia.org/wiki/HTTP_303
Отредактируйте проблемы с адресами:
"Как мне создавать свои ресурсы?" является важным вопросом для меня; "Как мне создавать URL-адреса?" рассматривается в двух областях:
URL-адреса, которые пользователи будут видеть, не должны быть слишком уродливыми и значимыми, если это возможно; если вы хотите, чтобы файлы cookie отправлялись в запросах на какой-либо ресурс, но не на других, вам нужно структурировать пути и пути к файлам cookie.
Если JRandomUser
хочет посмотреть его собственный профиль и вы хотите, чтобы URL был более симпатичным, чем foo.com/user/JRandomUser
или foo.com/user/(JRandom numeric user id here)
, вы могли бы сделать отдельный URL-адрес только для того, чтобы пользователь мог посмотреть свою собственную информацию:
GET foo.com/profile /*examines cookies to figure out who
* is logged in (SomeUser) and then
* displays the same response as a
* GET to foo.com/users/SomeUser.
*/
Я бы требовал невежества гораздо легче, чем мудрости по этому вопросу, но вот несколько соображений дизайна ресурсов:
GET foo.com/profile/
), было бы это частью, как предложил momo, уровня представления? Другими словами, что именно должен возвращать этот GET
? Веб-страница или какой-то JSON?
GET
, POST
, PUT
и DELETE
ресурсы. Веб-сайт - это просто еще одна платформа для доступа к API. Другими словами, дизайн URL сайта совершенно отличается от дизайна RESTful API. Пожалуйста, скажите мне, если я все еще не прав, ха-ха.
RESTful может использоваться как ориентир для создания URL-адресов, и вы можете создавать сеансы и ресурсы пользователей:
GET /session/new
получает веб-страницу с формой входаPOST /session
аутентифицирует учетные данные для базы данныхDELETE /session
уничтожает сеанс и перенаправляет на /GET /users/new
получает веб-страницу с регистрационной формойPOST /users
записывает введенную информацию в базу данных как новый /user/xxx GET /users/xxx
//получает и отображает текущие пользовательские данные в представлении профиляPOST /users/xxx
//обновляет новую информацию о пользователеОни могут быть множественными или единственными (я не уверен, какой из них правильный). Обычно я использовал /users
для пользовательской индексной страницы (как и ожидалось) и /sessions
, чтобы узнать, кто вошел в систему (как и ожидалось).
Использование имени в URL вместо числа (/users/43
vs. /users/joe
) обычно обусловлено желанием быть более дружелюбным к пользователям или поисковым системам, а не к каким-либо техническим требованиям. Все в порядке, но я бы рекомендовал вам быть последовательным.
Я думаю, что если вы пойдете с регистром /login/logout или sign(in|up|out)
, это не сработает с успокоительной терминологией.
/new
не добавляется в GET /session/
non RESTful? Я слышал, что глаголы обычно оставляют за глаголами HTTP ( GET
, POST
и т. Д.).
Сеансы не RESTful
Да, я знаю. Это делается, как правило, с OAuth, но на самом деле сеансы не RESTful. Вы не должны иметь ресурс /login/logout, потому что у вас не должно быть сеансов.
Если вы собираетесь это сделать, сделайте его RESTful. Ресурсы - существительные и /login и/logout - не существительные. Я бы пошел с /session. Это делает создание и удаление более естественным действием.
POST и GET для сеансов легко. Если вы отправляете пользователя/пароль в качестве переменных, я бы использовал POST, потому что я не хочу, чтобы пароль был отправлен как часть URI. Он появится в журналах и, возможно, будет выставлен по проводам. Вы также рискуете, что программное обеспечение завершится с ошибкой GET args.
Обычно я использую Basic Auth или no Auth с сервисами REST.
Создание пользователей
Это один ресурс, поэтому вам не нужно/зарегистрироваться.
Какой тип идентификатора используется, это сложный вопрос. Вы должны думать об обеспечении уникальности, о повторном использовании старых идентификаторов, которые были DELETEd. Например, вы не хотите использовать эти идентификаторы как внешние ключи на бэкэнд, если идентификаторы будут переработаны (если это вообще возможно). Однако для внешнего/внутреннего преобразования идентификаторов вы можете искать, чтобы уменьшить требования к бэкэнд.
Я просто расскажу о своем опыте интеграции различных веб-сервисов REST для своих клиентов, будь то для мобильных приложений или для связи между серверами и серверами, а также для создания REST API для других. Вот несколько замечаний, которые я собрал из других REST API других людей, а также те, которые мы создали сами:
GET /register // gets the webpage that has the registration form
GET /logout // destroys session and redirects to / POST /login // authenticates credentials against database and either redirects home with a new session or redirects back to /login
Поскольку REST разрабатываются как службы, такие функции, как вход и выход из системы, обычно возвращают результат успеха/отказа (обычно в формате JSON или XML), который затем потребитель интерпретирует. Такая интерпретация может включать перенаправление на соответствующую веб-страницу, как вы упомянули
GET /register // gets the webpage that has the registration form POST /register // records the entered information into database as a new /user/xxx
Вот некоторые моменты из того, что я имел в виду. Я надеюсь, что это может дать вам некоторые идеи.
Теперь, насколько это возможно для реализации вашего REST, это типичная реализация, с которой я столкнулся:
GET /logout
Выполнить выход в бэкэнд и вернуть JSON для обозначения успеха/отказа операции
POST /login
Отправьте учетные данные на сервер. Возвратите успех/неудачу. В случае успеха обычно он также возвращает токен сеанса, а также информацию профиля.
POST /register
Подать заявку на бэкэнд. Возвратите успех/неудачу. В случае успеха обычно обрабатывается то же самое, что и успешный вход в систему, или вы можете выбрать регистрацию в качестве отдельной службы.
GET /user/xxx
Получить профиль пользователя и вернуть формат данных JSON для профиля пользователя
POST /user/xxx // renamed to POST /updateUser/xxx
Опубликовать обновленную информацию о профиле как формате JSON и обновить информацию в бэкэнд. Вернуть успех/отказ вызывающему абоненту
Использование и разработка API-интерфейсов - это не только визуально привлекательные URL-адреса, но и URL-адреса, которые имеют смысл. Для регистрации пользователя/входа в систему я использовал их в прошлом:
GET /user // Get multiple user info (limit ~10)
GET /user/1 // Get single user info
POST /user // Create user (registration)
PUT /user/1 // Edit user
POST /user/1/login // Login (could be GET, but I like sending more secure params by POST)
GET /user/1/logout // Logout
Я считаю, что это подход RESTful к аутентификации. Для LogIn вы используете HttpPut
. Этот метод HTTP может использоваться для создания, когда ключ предоставляется, а повторные вызовы являются идемпотентными. Для LogOff вы указываете тот же путь в методе HttpDelete
. Нет глаголов. Надлежащая коллективная плюрализация. Методы HTTP поддерживают цель.
[HttpPut]
[Route("sessions/current")]
public IActionResult LogIn(LogInModel model) { ... }
[HttpDelete]
[Route("sessions/current")]
public IActionResult LogOff() { ... }
При желании вы можете заменить ток на активный.
Я бы рекомендовал использовать URL-адрес учетной записи пользователя, похожий на твиттер, где URL-адрес учетной записи пользователя был бы похож на foo.com/myUserName
так же, как вы можете попасть в мою учетную запись Twitter с URL https://twitter.com/joelbyler
Я не согласен с выходом из системы, требующей POST. Как часть вашего API, если вы собираетесь поддерживать сеанс, тогда идентификатор сеанса в форме UUID может быть тем, что можно использовать для отслеживания пользователя и подтверждения того, что действие, которое принято, разрешено. Тогда даже GET может передать идентификатор сеанса на ресурс.
Короче говоря, я бы порекомендовал вам сохранить его простым, URL-адрес должен быть незабываемым.