Если приложения REST должны быть неактивными, как вы управляете сеансами?

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

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

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

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

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

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

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

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


Обновить:

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

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

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

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

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

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

Состояние приложения клиента никогда не должно храниться на сервере, а передаваться от клиента к каждому месту, которое в нем нуждается.

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

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

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

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

Существуют некоторые основные принципы реализации:

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

Таким образом, пять ключевых принципов :

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Да. Предоставьте фильтр в запросе URI RESTful.

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

Да. Насколько велик этот «список отправителей сообщений»? Краткий список ПК?

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

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

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

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

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

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

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

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

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

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

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

Проверка подлинности

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

Аутентификация на основе форм не используется службами REST. Однако, как отмечено выше, службы REST не предназначены для вызова пользователем, а приложением. Приложение должно управлять получением токена аутентификации. В моем случае я использовал cookies с JASPIC с OAuth 2.0 для подключения к Google для проверки подлинности и простой проверки подлинности HTTP для автоматического тестирования. Я также использовал аутентификацию HTTP Header через JASPIC для локального тестирования (хотя такой же подход можно использовать и в SiteMinder)

В соответствии с этими примерами аутентификация управляется на стороне клиента (хотя SiteMinder или Google будут хранить сеанс аутентификации на своем конце), ничего не может быть сделано в отношении этого состояния, но оно не является частью приложения REST.

Запросы на получение

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

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

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

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

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

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

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

голосование

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

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

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

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

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

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


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

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

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

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

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

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


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


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

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

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

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

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

Да, мы также можем поддерживать сеанс в webservice независимо от того, является ли он REST или SOAP. Он может быть реализован с использованием любой сторонней библиотеки или вы можете реализовать самостоятельно.

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

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

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

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

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

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

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

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

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

Взгляните на эту презентацию.

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

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

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

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

Вы должны управлять клиентским сеансом на стороне клиента. Это означает, что вы должны отправлять данные аутентификации с каждым запросом, и, возможно, вам не нужно иметь кэш-память в памяти на сервере, который связывает данные auth с данными пользователя, такими как идентификатор, разрешения и т. Д. …

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

Вся концепция отличается … Вам не нужно управлять сеансами, если вы пытаетесь внедрить протокол RESTFul. В этом случае лучше выполнять процедуру аутентификации по каждому запросу (тогда как для нее есть дополнительные затраты с точки зрения производительности – хеширование пароля было бы хорошим примером, а не большой проблемой …). Если вы используете сеансы – как вы можете распределять нагрузку на несколько серверов? Уверен, что протокол RESTFul предназначен для устранения сеансов вообще – вам они действительно не нужны … Вот почему он называется «без гражданства». Сеансы требуются только в том случае, если вы не можете хранить что-либо, кроме Cookie, на стороне клиента после того, как был сделан запрос (например, возьмите старый браузер, не поддерживающий Javascript / HTML5). В случае «полнофункционального» клиента RESTFul обычно безопасно хранить base64(login:password) на стороне клиента (в памяти) до тех пор, пока приложение не будет загружено – приложение используется для доступа к единственному хосту и файлу cookie не могут быть скомпрометированы сторонними скриптами …

Я бы настоятельно рекомендовал отключить аутентификацию cookie для служб RESTFul … проверить Basic / Digest Auth – этого должно быть достаточно для служб на основе RESTFul.

REST является апатридом и не поддерживает никаких состояний между запросами. Клиентские cookies / заголовки настроены на поддержание состояния пользователя, такого как аутентификация. Скажем, имя пользователя / пароль клиента проверены механизмом аутентификации третьей части. 2-й уровень OTP gerneation и т. Д. После того, как пользователь получил аутентификацию – заголовки / куки-файлы приходят на остановку конечной точки обслуживания, и мы можем предположить, что пользователь является auth, так как пользователь приходит с действующими заголовками / файлами cookie , Теперь определенная информация о пользователе, подобном IP, либо сохраняется в кеше, а после этого, если запрос поступает с одного и того же Ip (MAC-адрес) для перечисленных ресурсов. Пользователь разрешен. И кеш сохраняется в течение определенного времени, который становится недействительным после истечения времени. Таким образом, можно использовать либо кеш, либо записи БД, которые могут использоваться для сохранения информации по запросу.

Давайте будем гением компьютера.