Если REST-приложения должны быть без сохранения состояния, как вы управляете сессиями? - PullRequest
489 голосов
/ 24 июня 2010

Мне нужны некоторые разъяснения.Я читал о REST и создании приложений RESTful.Согласно википедии, сам REST определен как Представительный государственный перевод .Поэтому я не понимаю всех этих gobbledeygook , которые все продолжают извергать.

Из википедии:

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

Они просто говорят: «t использовать хранилище данных уровня сеанса / приложения ???

Я понял, что одна из целей REST - сделать доступ к URI согласованным и доступным, например, вместо того, чтобы скрывать запросы подкачки внутри постов, делая номер страницы запроса частью GET URI.Имеет смысл для меня.Но кажется, что это просто выходит за рамки, говоря, что нет на данные клиента (данные сеанса) должны когда-либо храниться на стороне сервера.

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

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

Опять же, просто пытаюсь понять это.Кто-то уточните .


Обновление:

Я нашел вопрос о переполнении стека, ответ на который не совсем помог мне: Какуправлять состоянием в REST , что говорит о том, что важное состояние клиента должно передаваться всем при каждом запросе .... Ugg .. похоже на большие издержки ... Это правильно?

Ответы [ 16 ]

473 голосов
/ 24 июня 2010

Основное объяснение:

Нет состояния сеанса клиента на сервере.

Без сохранения состояния это означает, что сервер не хранит никакого состояния о клиентском сеансе на стороне сервера.

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

Это не мешает другим службам, с которыми общается веб-сервер, поддерживать состояние о бизнес-объектах, таких как корзины покупок, но не о текущем состоянии приложения / сеанса клиента.

Состояние приложения клиента *1023* никогда не должно храниться на сервере, а передаваться из клиента во все места, где это необходимо.

Отсюда ST в REST , State Transfer . Вы передаете состояние вместо того, чтобы сервер сохранял его. Это единственный способ масштабирования до миллионов одновременно работающих пользователей. Если ни по какой другой причине, кроме как потому, что миллионы сеансов - это миллионы сеансов.

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

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

Без сохранения состояния - это то, как протокол HTTP и сеть в целом были разработаны для работы, и это в целом более простая реализация, и у вас есть один путь кода вместо набора логики на стороне сервера для поддержки группы состояния сеанса.

Есть несколько очень простых принципов реализации:

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

В итоге, пять ключевых принципов :

  1. Дайте каждой «вещи» удостоверение личности
  2. Связать вещи вместе
  3. Используйте стандартные методы
  4. Ресурсы с несколькими представлениями
  5. Общаться без гражданства

Нет ничего об аутентификации или авторизации в REST диссертация .

Потому что ничто не отличается от аутентификации запроса, который является RESTful, от запроса, который не является. Аутентификация не имеет отношения к обсуждению RESTful.

Объяснение того, как создать приложение без сохранения состояния для ваших конкретных требований, слишком широк для StackOverflow.

Реализация аутентификации и авторизации в части, касающейся REST, еще более слишком широка , а различные подходы к реализации подробно описаны в Интернете в целом.

Комментарии с просьбой о помощи / информации по этому желанию / должны быть помечены как Больше не нужно .

279 голосов
/ 24 июня 2010

Отсутствие состояния означает, что каждый HTTP-запрос происходит в полной изоляции.Когда клиент делает HTTP-запрос, он включает в себя всю информацию, необходимую серверу для выполнения этого запроса.Сервер никогда не полагается на информацию из предыдущих запросов.Если эта информация важна, клиент должен будет отправить ее снова в последующем запросе.Безгражданство также приносит новые возможности.Проще распределить приложение без сохранения состояния между серверами с балансировкой нагрузки.Приложение без сохранения состояния также легко кэшируется.

На самом деле существует два типа состояний.Состояние приложения на клиенте и Состояние ресурса на сервере.

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

Состояние ресурса одинаково для каждого клиента, и его правильное место на сервере.Когда вы загружаете изображение на сервер, вы создаете новый ресурс: новое изображение имеет свой собственный URI и может быть целью будущих запросов.Вы можете получить, изменить и удалить этот ресурс через HTTP.

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

75 голосов
/ 24 июня 2010

Они просто говорят, что не используют хранилище данных уровня сеанса / приложения ???

Нет. Они не говорят об этом тривиальным образом.

Они говорят, что не определяют "сессию". Не входите Не выходите из системы. Предоставьте учетные данные вместе с запросом. Каждый запрос стоит отдельно.

У вас все еще есть хранилища данных. У вас все еще есть аутентификация и авторизация. Вы просто не тратите время на установление сеансов и поддержание состояния сеанса.

Дело в том, что каждый запрос (а) стоит совершенно один и (б) может быть тривиально перенесен в гигантскую параллельную ферму серверов без какой-либо реальной работы. Apache или Squid могут передавать запросы RESTful вслепую и успешно.

Что если бы у меня была очередь сообщений, и мой пользователь хотел прочитать сообщения, но, читая их, хотел заблокировать поступающие сообщения определенных отправителей на время его сеанса?

Если пользователю нужен фильтр, просто укажите фильтр для каждого запроса.

Разве не имеет смысла ... сервер отправлять только те сообщения (или идентификаторы сообщений), которые не были заблокированы пользователем?

Да. Укажите фильтр в запросе RESTful URI.

Действительно ли мне нужно отправлять полный список отправителей сообщений для блокировки каждый раз, когда я запрашиваю новый список сообщений?

* * 1028 Да. Насколько большим может быть этот «список отправителей сообщений для блокировки»? Краткий список ПК?

Запрос GET может быть очень большим. При необходимости вы можете попробовать запрос POST, даже если он звучит как запрос.

35 голосов
/ 24 июня 2010

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

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

Это компромисс.

32 голосов
/ 25 июля 2014

Исторический обзор управления состоянием пользовательских приложений

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

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

HTML5 и XML Header Request со временем стандартизировали понятие хранения сложных данных, включая состояние приложения стандартным способом на стороне клиента (т.е. браузера), не прибегая к переходу назад и вперед между сервером.

Общее использование услуг REST

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

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

1017 * удостовер * Для любого запроса к серверу часть запроса должна содержать токен авторизации. Как это реализовано, зависит от конкретного приложения, но в целом это форма аутентификации BASIC или CERTIFICATE. Проверка подлинности на основе форм не используется службами REST. Однако, как отмечено выше, службы REST предназначены не для вызова пользователем, а для приложения. Приложение должно управлять получением токена аутентификации. В моем случае я использовал куки с JASPIC с OAuth 2.0 для подключения к Google для аутентификации и простой HTTP-аутентификации для автоматического тестирования. Я также использовал HTTP-аутентификацию заголовка через JASPIC для локального тестирования (хотя такой же подход может быть выполнен в SiteMinder) В соответствии с этими примерами аутентификация управляется на стороне клиента (хотя SiteMinder или Google сохраняют сеанс аутентификации на их конце), с этим состоянием ничего нельзя поделать, но это не является частью службы REST. применение. Запрос на получение

Запросы на получение в REST - это GET операции, когда определенный ресурс запрашивается и кэшируется. Нет необходимости в сеансах сервера, потому что в запросе есть все, что нужно для извлечения данных: аутентификация и URI.

Сценарии транзакций

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

Что это означает для служб REST [если все сделано правильно], так это принять один запрос к серверу REST, который будет содержать все, что необходимо для однопользовательской операции, которая выполняет все, что необходимо в одной транзакции, Сценарий транзакции - это то, что называется шаблоном.

Обычно это делается с помощью запроса POST, но могут использоваться и другие, такие как PUT.

Множество надуманных примеров REST (я сам это делал) пытался следовать как можно большему количеству того, что было определено в протоколе HTTP, после того как я решил стать более прагматичным и оставил его на GET и Только по почте . Метод POST даже не должен реализовывать шаблон POST-REDIRECT-GET.

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

Опрос

Хотя REST также можно использовать для опроса, я не буду рекомендовать его, если вы не будете использовать его из-за совместимости браузера. Для этого я бы использовал WebSockets, для которых я также разработал API-контракт . Еще одна альтернатива для старых браузеров - CometD.

25 голосов
/ 10 января 2016

REST очень абстрактный.Это помогает иметь несколько хороших, простых, реальных примеров.

Возьмем, к примеру, все основные приложения для социальных сетей - Tumblr, Instagram, Facebook и Twitter.Все они имеют вид с непрерывной прокруткой, где чем дальше вы прокручиваете вниз, тем больше контента вы видите, все дальше и дальше назад во времени.Тем не менее, мы все пережили тот момент, когда вы теряете то, куда вас прокручивали, и приложение сбрасывает вас обратно наверх.Например, если вы выходите из приложения, то при повторном его открытии вы снова возвращаетесь наверх.

Причина в том, что сервер не сохранил ваше состояние сеанса.К сожалению, ваша позиция прокрутки была просто сохранена в RAM на клиенте.

К счастью, вам не нужно повторно входить в систему при повторном подключении, но это только потому, что ваш сохраненный сертификат входа в систему на стороне клиента также не истек.Удалите и переустановите приложение, и вам придется снова войти в систему, поскольку сервер не связал ваш IP-адрес с вашим сеансом.

У вас нет сеанса входа в систему на сервере, потому что они соблюдают REST.


Теперь приведенные выше примеры вообще не связаны с веб-браузером, но набэкэнд, приложения связываются через HTTPS со своими хост-серверами.Я хочу сказать, что REST не должен включать файлы cookie, браузеры и т. Д. Существуют различные способы хранения состояния сеанса на стороне клиента.

Но давайте поговорим о веб-браузерах на секунду, потому что это поднимает еще одно важное преимущество REST, о котором никто здесь не говорит.

Если сервер попытался сохранить состояние сеанса, как он?должен идентифицировать каждого отдельного клиента?

Он не может использовать свой IP-адрес, потому что многие люди могут использовать этот же адрес на общем маршрутизаторе.Так как же тогда?

Он не может использовать MAC-адрес по многим причинам, не в последнюю очередь из-за того, что вы можете войти в несколько учетных записей Facebook одновременно в разных браузерах и в приложении.Один браузер может легко притвориться другим, а MAC-адреса так же легко подделать.

Если серверу нужно хранить какое-то состояние на стороне клиента, чтобы идентифицировать вас, он должен хранить его в ОЗУ дольшепросто время, необходимое для обработки ваших запросов, или же оно должно кэшировать эти данные.Серверы имеют ограниченный объем оперативной памяти и кеша, не говоря уже о скорости процессора.Состояние на стороне сервера добавляет ко всем трем экспоненциально.Кроме того, если сервер собирается хранить какое-либо состояние о ваших сеансах, он должен хранить его отдельно для каждого браузера и приложения, в котором вы в настоящий момент вошли, а также для каждого используемого вами другого устройства.


Итак ... Я надеюсь, что вы теперь понимаете, почему REST так важен для масштабируемости.Я надеюсь, что вы начнете понимать, почему состояние сеанса на стороне сервера связано с масштабируемостью сервера, а наковальни - с ускорением автомобиля.


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

12 голосов
/ 04 января 2016

Я вижу, что основной проблемой здесь является смешивание Session с State .И хотя REST указывает, что вам НЕ следует хранить State на сервере, ничто не мешает вам сохранить пользователя Session .

Управление State на сервере означает, что ваш сервер точно знает, что делает клиент (какую страницу они просматривают в каком разделе приложения).И это то, что вам не нужно делать.

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

Кто-то может поспорить, что клиенту лучше сгенерировать токен.Я говорю, что это работает в обоих направлениях, и это будет зависеть от приложения и от того, кто будет работать с API.

Кроме того, правильное хранение некоторых конфиденциальных данных сеанса на сервере должно быть правильным способом.Вы не можете доверять клиенту хранить его корзину покупок, которая (например) содержит поле с именем «isFreeGift».Такая информация должна храниться на сервере.

Ссылка на видео, предоставленная Сантану Дей в его ответе, полезна.Посмотрите, если нет.

Просто примечание: кажется, что все уже даные ответы игнорируют тот факт, что некоторые операции могут вызвать большую нагрузку на сервер.Это актуально с точки зрения энергопотребления, потребления оборудования и стоимости (для серверов, арендуемых по циклу ЦП).Хороший разработчик не должен быть ленивым в оптимизации своего приложения, даже если операция может быть выполнена очень быстро на современном процессоре на некотором арендованном сервере, за который они не оплачивают счет за электроэнергию и обслуживание.

В общемвопросу несколько лет, я надеюсь, что мой ответ все еще будет полезен.

11 голосов
/ 04 сентября 2014

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

Банковское приложение является примером приложения с сохранением состояния. Там, где пользователь сначала авторизуется, затем совершает транзакцию и выходит из системы. Если после выхода из системы пользователь попытается совершить транзакцию, он не сможет это сделать.

Да, протокол HTTP, по сути, является протоколом без сохранения состояния, но для придания ему состояния мы используем файлы cookie HTTP. Итак, SOAP по умолчанию. Но это также может быть сделано с учетом состояния, в зависимости от используемой вами структуры.

HTTP не имеет состояния, но все же мы можем поддерживать сеанс в нашем Java-приложении, используя другой механизм отслеживания сеансов.

Да, мы также можем поддерживать сеанс в веб-сервисе, будь то REST или SOAP. Это может быть реализовано с помощью любой сторонней библиотеки или вы можете реализовать самостоятельно.

Взято из http://gopaldas.org/webservices/soap/webservice-is-stateful-or-stateless-rest-soap

5 голосов
/ 06 декабря 2012

Посмотрите на эту презентацию.

http://youtu.be/MRxTP-rQ-S8

В соответствии с этим шаблоном - создавать временные спокойные ресурсы для управления состоянием, если и когда это действительно необходимо. Избегайте явных сессий.

3 голосов
/ 22 мая 2015

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

ИМО, API должен быть без учета состояния, что дает возможность действительно быстро масштабироваться.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...