Подтвердить что ты не робот

Безгражданство REST api с аутентифицированными пользователями

В настоящее время я разрабатываю REST Http api. (С помощью материала HATEOAS, чтобы сделать клиентов "более простыми" и избегать того, чтобы клиенты делали сложные вещи, вместо того, чтобы позволить api сказать им, что делать...)

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

Чтобы аутентифицировать пользователей, мы будем использовать OAuth, легко.

Итак, в клиенте (приложение ios...) случайный пользователь может увидеть список пользователей, который должен увидеть:

Adrien: Following
John:   Not Following
Rambo:  Not Following

И другой пользователь мог бы увидеть:

Adrien: Following
John:   Not Following
Rambo:  Following

Чтобы достичь этого, первое решение будет для клиента (в срок, приложение iphone/web/etc), чтобы получить список всех пользователей, прошедших проверку подлинности, и каждый раз, когда клиент отображает список, сравните каждого пользователя со списком следующих пользователей, чтобы узнать, должно ли оно отображаться "Не следует" или "Следующее".

Запросами/ответами будут:

GET /users
Authorization: OAuth token...

[
  {"id": 1, "name": "Adrien"},
  {"id": 2, "name": "John"},
  {"id": 3, "name": "Rambo"}
]

и

GET /users/{myid}/following
Authorization: OAuth token...

[1, 3, 25, 1210, 9]

Это, кажется, совершенно, без гражданства. Хорошо.

Теперь, что, если я хочу облегчить жизнь заказчикам и встраивать непосредственно в ответ списка пользователей, отношение каждого пользователя относительно аутентифицированного пользователя:

GET /users
Authorization: OAuth token...

[
  {"id": 1, "name": "Adrien", "relationship": "Following"},
  {"id": 2, "name": "John", "relationship": "Not Following"},
  {"id": 3, "name": "Rambo", "relationship": "Following"}
]

Итак, вопросы:

  • Кажется, что он сломал "безгосударственную" вещь, действительно ли она нарушает ограничение REST без ограничения состояния?
  • Далее, считаете ли вы, что для api это хорошая или плохая практика?
4b9b3361

Ответ 1

Вы должны обязательно вставлять отношения в ответ списка пользователей. Было бы плохой практикой, чтобы заставить клиентов рассчитать ее.

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

Наконец, я думаю, что вы не полностью получаете "State" часть Hypermedia как двигатель приложения State. В основном, ресурсы - это государственные машины. Когда вы GET ресурс, представлены действительные переходы состояния, в ответах есть элементы управления гиперссылками (ссылки и формы). Следуя этим ссылкам и отправляя формы, клиент может изменить состояние этих ресурсов.

Ответ 2

Включение описания типа отношения в тело ответа не нарушает ограничение без сохранения. Ограничение без сохранения означает, что веб-сервер может отвечать на запрос без зависимости от предыдущего запроса (как упоминалось Tom, Jacob и kgb).

Я не могу сказать, является ли то, что вы делаете, это "лучшая практика" или нет, но в целом Рой дал следующие причины и против того, чтобы ваш API был без гражданства (см. раздел 5.1.3 его dissertation). Как и многие вещи в жизни, существует компромисс:

Проблемы с системой без гражданства

  • Запросы могут быть больше. Поскольку данные не хранятся на сервере между запросами, каждый запрос может потребовать включения одинаковых вещей снова и снова.

  • В системе без состояния сервер зависит от правильного состояния клиента.

Преимущества системы без гражданства

  • Вы знаете, к чему стремится запрос, основанный исключительно на его содержании.

  • Надежность, поскольку она "облегчает задачу восстановления после частичных отказов". См. ссылка 133, приведенная в Ройс для получения дополнительной информации.

  • Улучшена масштабируемость. Управление состоянием между запросами, особенно в распределенной среде, может быть довольно сложным. Первое, что приходит в голову здесь, - это состояние сеанса ASP.NET InProc, отлично подходит для одного сервера, один экземпляр процесса, но он не очень хорошо масштабируется.

Ресурсы RESTful

Кроме того, согласно определению Roy ресурса, я бы поставил вопрос о том, как я думаю, что вы определяете свои ресурсы, причем каждый пользователь получает незначительное "представление" данных. Рой определяет ресурс как функцию членства, которая изменяется со временем (см. Раздел 5.2.1.1 в dissertation). Ресурс списка пользователей, который вы определили выше, изменяется как по времени, так и по заголовку авторизации. Два разных клиента, запрашивающих/пользователей, в то же время, скорее всего, получат совершенно разные результаты. Это затруднит кэширование результатов.

EDIT: Использование заголовка HTTP-изменения позволяет кэшировать его.

Ответ 3

Если вы считаете, что добавление свойства "отношения" для пользователей, нарушающих ограничение без сохранения, добавляет его, когда "/follow" находится в запросе, также ломает его.

Я бы сказал, что "без гражданства" означает, что никакой ответ не зависит от других запросов/ответов.

HTTP - это stateless протокол, но он может хранить довольно много данных о пользователе в заголовках запроса/ответа (и я не говорю о сеансах/куках)

Ответ 4

От Roy Fieldings Архитектурные стили и Проектирование сетевых архитектур:

3.4.3 Client-Stateless-Server (CSS)

The client-stateless-server style derives from client-server with the additional
constraint that no session state is allowed on the server component. 
Each request from client to server must contain all of the information necessary 
to understand the request, and cannot take advantage of any stored context on 
the server. Session state is kept entirely on the client.

Ссылка: http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm

Таким образом, вы встраиваете данные сущности непосредственно в ответ, не делаете свое решение без апатридов.

По хорошей практике:

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

Однако, в зависимости от объема данных для каждого пользователя, вы можете рассмотреть возможность предоставления списка ссылок на ресурс пользователя и указать также "следовать". Затем клиент может получить данные о необходимых пользователях. Какое решение, которое вы выбираете, должно зависеть от того, что, по вашему мнению, потребуется клиенту, может привести к нескольким подходам.

Ответ 5

Я не вижу корреляции между вложением информации о соотношении в ресурс /users и ограничение без сохранения. Поэтому я не вижу проблемы.

Однако я бы сказал, что вы нарушаете ограничение "идентификация ресурсов".

/users для вас и /users для меня будет показан совершенно другой набор отношений. Я бы сказал, что это два разных ресурса и поэтому должны иметь разные URI.

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