Как сделать мое веб-приложение не имеющим состояния, но при этом делать что-то полезное?

Я видел этот совет ...

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

... и я прочитал страницу Википедии http://en.wikipedia.org/wiki/REST и это действительно звучит хорошо, но я не понимаю, как это реализовать. Я работаю в ASP .NET Webforms, а не в MVC.

Например, в приложении, которое я собираюсь создать, мне нужно, чтобы мой пользователь вошел в систему, прежде чем я позволю им что-либо делать. Есть пара обручей, которые им нужно пройти, прежде чем им позволят сделать много полезного - например, принять Т и Т и подтвердить, что их основные детали не изменились. Наконец, им разрешено делать то, что они действительно хотят, например BuyAProduct!

Мне кажется (я пришел из ТЯЖЕЛОГО состояния богатого клиента), что мне нужно состояние, чтобы записывать, что они сделали, и делать из этого заключения, что им разрешено делать. Я не понимаю, как я могу поддержать их (скажем) закладкой URI BuyAProduct. Когда они дойдут до закладки, как я узнаю, вошли ли они в систему, согласились ли они с T и C и внимательно ли они проверили свои основные данные?

Мне нравится идея приложения без сохранения состояния, отчасти потому, что оно, кажется, полностью решает проблему «Что, черт возьми, мне делать, когда пользователь нажимает кнопки« Назад »и« Вперед »?» Я не понимаю, как мне еще заставить его работать должным образом. Я чувствую, что упускаю в этом что-то действительно фундаментальное.


person RichardHowells    schedule 10.06.2010    source источник
comment
Почему? Если он сейчас работает, зачем менять? Веб-приложения, как правило, должны поддерживать отслеживание состояния, отсюда - сеансы и файлы cookie.   -  person John Gietzen    schedule 10.06.2010
comment
Ах, он не работает, так как еще не построен. Думаю о вариантах дизайна. Отредактирую вопрос.   -  person RichardHowells    schedule 10.06.2010
comment
@John Я могу заверить, что веб-приложениям не нужно использовать сеансы и файлы cookie.   -  person Darrel Miller    schedule 11.06.2010
comment
@ Даррел Миллер: Что, если вы хотите разрешить пользователям входить в приложение?   -  person John Gietzen    schedule 11.06.2010
comment
@John Заголовок авторизации http позволяет вам предоставить учетные данные с запросом, который может гарантировать, что человек, выполняющий запрос, является тем, кем они являются, и имеет достаточные полномочия для выполнения запроса. Что делает вход в систему, чего нельзя добиться с помощью заголовка авторизации?   -  person Darrel Miller    schedule 11.06.2010
comment
@Darrel: Можете ли вы использовать OpenID с заголовком авторизации?   -  person John Gietzen    schedule 11.06.2010


Ответы (5)


Совет не предполагает, что приложение не должно иметь состояния - он предполагает, что ресурсы в приложении не должны иметь состояния. То есть страница под названием «www.mysite.com/resources/123» всегда будет представлять один и тот же ресурс, независимо от того, какой пользователь обращается к нему, и независимо от того, вошли ли они в систему или нет.

(Тот факт, что вы можете запретить доступ не вошедшему в систему пользователю, - это отдельная проблема - дело в том, что сам Uri не полагается на пользовательские данные для работы.)

Например, сайты, нарушающие это правило, - это те, на которых вы переходите на страницу продукта, отправляете URI по электронной почте своему другу, и, щелкнув его, они видят сообщение типа «Извините, срок вашего сеанса истек. "или" Этого продукта не существует "или аналогичный. Причина, по которой это происходит, заключается в том, что Uri включает что-то особенное для пользовательского сеанса на сайте, и если другой пользователь пытается использовать ссылку (или тот же пользователь позже), он больше не действительный.

Таким образом, вам всегда будет нужна какая-то форма состояния для вашего приложения, но то, где это состояние реализовано, является важным фактором.

Надеюсь, это поможет пролить немного света!

person Dan Puzey    schedule 10.06.2010
comment
Было бы полезно отметить, что в некоторых случаях ресурсы зависят от пользователя, поэтому только авторизованные пользователи будут видеть одни ресурсы, а не другие. Таким образом, доступны пользовательские взаимодействия. - person ; 11.06.2010
comment
Да, но Uri этого ресурса должен оставаться одинаковым для всех пользователей, независимо от того, есть у них доступ или нет. (Например, если бы это было приложение REST, Uri возвращал бы состояние Http Not Authorized, где это необходимо, вместо ресурса). - person Dan Puzey; 13.06.2010
comment
Значит, в клиенте должно сохраняться состояние? Скажем, у меня есть ссылка на человека www.XXXX.com/persom/Tom, и этот веб-сайт откажет в доступе постороннему, если я его друг, я скопирую эту ссылку, и я увижу его сообщение, а если я Если я незнакомец, это будет запрещено. Могу ли я рассматривать эту связь как состояние, поскольку действительно один и тот же URI дает нам другую страницу. У него должно быть что-то, что нужно поддерживать на сервере, например в базе данных, чтобы поддерживать отношения. Если это своего рода состояние, и не имеет ли это приложение состояния? - person JaskeyLam; 21.11.2014
comment
Однако ваш тот же URL-адрес не должен указывать на другую страницу. Технически должно произойти то, что URL-адрес, когда он неавторизован, должен дать ответ HTTP 401, а страницу с ошибкой для этого URL-адреса можно настроить для отображения чего-то полезного (например, формы входа в систему). Хотя конечным результатом может быть просмотр пользователем другой страницы, ваш URL-адрес будет обслуживать только один ресурс в результате успешного запроса. Это тонкая разница, но в этом суть модели без гражданства. - person Dan Puzey; 21.11.2014

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

Чтобы прояснить этот момент, я не считаю, что веб-формы - это разумный выбор для REST, потому что концептуальная модель, на которой основаны WebForms, - это та, в которой вы абстрагируетесь от Интернета. Он был построен для имитации модели разработки VB.

REST охватывает HTTP и распределенную природу веб-приложений. Эти два подхода несовместимы.

person Darrel Miller    schedule 11.06.2010
comment
Нет, я думаю, вы ошибаетесь в том, что основной принцип, о котором он говорит, может в равной степени (и * должен) применяться и к WebForms: не помещайте информацию о состоянии в свой Uri. - person Dan Puzey; 11.06.2010
comment
@Dan Я думаю, что вы хотели сказать, что не помещайте ссылку на состояние сеанса сервера в URL-адресе. Помещение состояния клиентского приложения в URL-адрес - полностью успокаивающий подход. Независимо от того, находится ли состояние сеанса в URL-адресе или передается каким-либо другим способом, например с помощью файла cookie, состояние сеанса приводит к нарушению самоописательного ограничения REST. - person Darrel Miller; 11.06.2010
comment
Состояние приложения в Uri полностью противоречит принципам REST: если ваш Uri ресурса отличается от my Uri ресурса, это не RESTful Uri. - person Dan Puzey; 13.06.2010
comment
@Dan После добавления параметра запроса к URL-адресу вы ссылаетесь на другой ресурс. Ресурс идентифицируется не только по сегментам пути. - person Darrel Miller; 13.06.2010
comment
@Dan В примере google.com/search?q=rest поисковый запрос может считается состоянием приложения. - person Darrel Miller; 13.06.2010
comment
@Dan Вот еще более интересный пример: http://yuml.me/diagram/scruffy/class/[Resource]+1-%3E*[Represenations] - person Darrel Miller; 13.06.2010
comment
Это можно было бы считать государством, но это не так. Со временем он не меняется: это параметр, вход. Это не означает, что приложение будет меняться со временем от имени пользователя. - person Dan Puzey; 14.06.2010
comment
@Dan Мне было бы очень интересно, если бы вы могли указать мне какой-нибудь авторитетный источник, подтверждающий вашу точку зрения на состояние клиентского приложения. - person Darrel Miller; 14.06.2010
comment
@Darrel Я думаю, что Дэн имеет в виду модель зрелости Ричардсона: код. google.com/p/implementing-rest/wiki/RMM. Да, вы можете это сделать, и да, вы можете называть это RESTful. Но насколько это на самом деле RESTful? - person ; 15.06.2010
comment
@Ryan Это абсолютно RESTful. Он соответствует единому интерфейсу, сообщение самоописательное, это один из самых простых примеров HATEOAS и интересный пример использования виртуального пространства URI для идентификации ресурсов. Вот еще один пример: codestyle.org/servlets/ - person Darrel Miller; 15.06.2010

Поддерживать состояние ресурса - это нормально. «Запрет без сохранения состояния» относится только к состоянию сеанса.

Вот отрывок из основополагающего вывода REST Роя Филдинга:

Затем мы добавляем ограничение для взаимодействия клиент-сервер: обмен данными должен быть без сохранения состояния по своей природе, как в стиле клиент-сервер без сохранения состояния (CSS) в Разделе 3.4.3 (рис. 5-3), так что каждый запрос от клиента к server должен содержать всю информацию, необходимую для понимания запроса, и не может использовать какой-либо сохраненный контекст на сервере. Таким образом, состояние сеанса полностью зависит от клиента.

person Raymond Hettinger    schedule 01.06.2013
comment
Как это возможно, если клиент (веб-браузер) не может хранить какую-либо защищенную информацию (например, учетные данные)? - person BeniRose; 11.07.2016

Вот в чем дело: REST - это связь с отслеживанием состояния по протоколу без отслеживания состояния. Дело не в том, что REST не имеет состояния. WebForms позволяет сохранять состояние между запросами. Зачем это нужно? Это позволяет вам выполнять такие действия, как сортировка элементов в списке с помощью кнопок вверх / вниз, без необходимости обновлять базовый ресурс при каждом щелчке. Тебе это не нужно. Вы можете просто ПОСТАВИТЬ представление ресурса, чтобы оно выглядело правильным, или использовать JavaScript для редактирования вашего представления, а затем выполнить ПОСТАВЛЕНИЕ в конце, когда вы будете удовлетворены. (Обратите внимание, что я использовал PUT, а не POST. На самом деле вы заменяете представление, чтобы будущие GET получали правильное состояние.)

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

WebForms не поощряет это. Вы можете создавать системы RESTful в WebForms, но модель по умолчанию оттолкнет вас от нее в сторону подхода RPC. Я могу придумать два способа обойти это: Front Controller (в котором случае вам действительно стоит рассмотреть MVC) или использовать файлы .ashx почти для всего. Модель Postback довольно хорошо уничтожает любую реальную надежду на выполнение настоящего REST с реальными WebForms / .aspx (т.е. PUT и DELETE всегда являются POST и, следовательно, не работают в модели REST).

person Community    schedule 11.06.2010
comment
Согласно RFC2616 POST может использоваться для отправки объекта в ресурс обработки. Это не означает создание ресурса. Создание - только одно из применений POST. Нет необходимости использовать PUT и DELETE для RESTful. См. Этот FAQ code.google.com/p/implementing-rest/wiki/FAQ - person Darrel Miller; 11.06.2010
comment
@ Даррел Достаточно справедливо. Я, наверное, слишком сильно склоняюсь к откровенности. Проблема, которую я вижу, заключается в том, что слишком легко все объяснить, что приводит к RPC. - person ; 15.06.2010
comment
@Darrel Я сосредоточен на уровне 3 модели зрелости Ричардсона: код .google.com / p / implementation-rest / wiki / RMM. Ну может 2 уровень :) - person ; 15.06.2010
comment
Да, использование POST для многих вещей может легко вернуться к RPC, если люди не имеют четкого представления о других ограничениях REST. - person Darrel Miller; 15.06.2010

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

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

person danswain    schedule 11.06.2010