Re: know-your-http-well
От: Mamut Швеция http://dmitriid.com
Дата: 22.02.14 20:56
Оценка: 13 (6)
Залогинился только ради этого «срача».

1. Курить эту диаграмму, учить наизусть и знать, как «Отче Наш»: https://raw.github.com/for-GET/http-decision-diagram/master/httpdd.png (Она намного более полная и вменяемая, чем известная диаграмма Webmachine). Все понятия, что это такое, и как себя вести описано тут: https://github.com/for-GET/http-decision-diagram/tree/master/doc. Диаграмма позволяет правильно раздерибанить процентов 99 возникающих при запросе ситуаций и контролировать их (да, HTTP-заголовки существуют не просто для того, чтобы на них тупо смотреть).

2. В добавок к первому пункту: https://github.com/for-GET/know-your-http-well Тоже знать, как отче наш

Пояснение к первым двум пунткам: REST — это, по сути, HTTP с дополнительными абстракциями. 100% REST'а и его абстракций берутся только и исключительно из HTTP. Если вы не понимаете вышеперечисленного, о каком REST'е идет речь?

3. Richardson Maturity Model. Вам нужен уровень 3. HATEOAS — это адский звиздец, но когда его понимаешь, понимаешь «как мы без этого жили раньше-то?»

Пояснение к пункту 3. REST == Representational State Transfer. Передача состояния представления.

Мы передаем состояние.
Мы передаем состояние представления.

Мы не передаем данные. Мы не передаем объекты. Мы передаем какое-то состояние для какого-то представления этих данных. Как вы представляете эти данные — это ваши личные вопросы. Для того, чтобы различать разные представления (и их версии) у вас есть Content-Type/Accept (см. пункт 2):

GET /backoffice/orders/123
> Accept: application/vnd.klarna.com.backoffice.order-v1+json
< Content-Type: application/vnd.klarna.com.backoffice.order-v1+json
{
  "total_amount_excluding_tax": 100,
  "total_amount_including_tax": 120,
  "links": [
     {
       "rel": "self",
       "href": "/backoffice/orders/123"
     },
     {
       "rel": "https://restapi.klarna.com/backoffice/person",
       "href": "/backoffice/perons/100"
     },
     {
       "rel": "https://restapi.klarna.com/backoffice/shipping_address",
       "href": "/backoffice/orders/123/shipping_address"
     },
     {
       "rel": "https://restapi.klarna.com/backoffice/billing_address",
       "href": "/backoffice/orders/123/billing_address"
     },
     ...
  ]
}


GET /backoffice/orders/123
> Accept: application/vnd.klarna.com.backoffice.order.aggregated-v1+json
< Content-Type: application/vnd.klarna.com.backoffice.order.aggregated-v1+json
{
  "total_amount_excluding_tax": 100,
  "total_amount_including_tax": 120,
  "person": {
     "given_name": "Mamut",
     "family_name": "Nespit",
     "national_identification_number": "1234567890",
     ...
  },
  "items": [
     {
        "type": "physical",
        "qty": "1",
        "unit_price": "100",
        "total_amount": "100",
        "merchant_reference": "AC6788-901"
        ...
     }
  ]
  "links": [
     {
       "rel": "self",
       "href": "/backoffice/orders/123"
     },
     {
       "rel": "https://restapi.klarna.com/backoffice/person",
       "href": "/backoffice/perons/100"
     },
     {
       "rel": "https://restapi.klarna.com/backoffice/shipping_address",
       "href": "/backoffice/orders/123/shipping_address"
     },
     {
       "rel": "https://restapi.klarna.com/backoffice/billing_address",
       "href": "/backoffice/orders/123/billing_address"
     },
  ]
}


В первую репрезентацию можно посылать PATCH (или POST с X-HTTP- Method-Override) только с amount'ами. Во второй — что душе пожелается. Откуда у людей проблема с обновлением сотни элементов за один раз? От непонимания


4. Ваши друзья:

http://apiary.io для дизайна и тестирования (переключайтесь в старый формат, он более developer-friendly)
— JSON Schemas: http://json-schema.org Это — готовая документация для вас и ваших клиентов + дизайн + валидация
— Используйте стандарты! Их не идиоты писали https://github.com/for-GET/core-pegjs/tree/master/src

На правах рекламы:
https://github.com/klarna/jesse для валидации JSON Schemas
https://github.com/klarna/katt для тестирования REST-запросов используя старый формат Apiary Blueprints (виден в моих примерах выше)
— и дай бог в течение пары месяцев (полгода-год ) мы выпустим тулзу для внятного дизайна этих самых JSON-схем (на node.js, на радость хипстерам)

Насчет всего остального слушайте Синклера, он говорит правду.


dmitriid.comGitHubLinkedIn
Re[18]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 10.02.14 06:48
Оценка: 15 (3) +1
Здравствуйте, dimgel, Вы писали:

J>>обращается по урлу www.example.com/api/users/F889A953B7C543AB82762A2E02E299BF


D>А вот меня кстати ещё с книжки смущает кодировать id|login|api_key текущего юзера в URL. Если мне, к примеру, не нужно между юзерами ничего шарить, т.е. они полностью изолированы друго от друга, я хочу юзать /my/contacts вместо /users/KEY/contacts (или вместо прилагательного my принято что-то другое юзать) + HTTP authorization (пишут ещё про какой-то OAuth, но мне в него лениво и наверняка он браузерами не поддерживается).


Если ты твёрдо контекстом определил, что есть "my", и по дороге нет посторонних участников, то проблем нет.

Но REST в описанном виде рассчитан в том числе и на участие промежуточных HTTP proxy с локальными кэшами (типа знаменитого squid, или nginx frontend). (Прокси не обязан быть публичным, он может быть и внутренним только для целей данного сервиса — но он всё равно может быть.) Предположим, что содержимое ответа /my/contacts не настолько секретно, чтобы не доверять его промежуточным автоматическим участникам. Как ты сделаешь различение, что есть /my/contacts для клиента 1 и /my/contacts для клиента 2? Прокси не в состоянии это различить. Максимум, что ты можешь — сказать ему не кэшировать. Но даже в этом случае прокси имеет право соптимизировать, если идут одновременные запросы на один и тот же URL от разных участников и один из ответов ещё не отдан до конца. Авторизация, согласно RFC 2616 и тому подобным, не влияет на кэширование.

А если ты отказываешься от хотя бы потенциального допуска промежуточных прокси — это становится уже не REST, а просто каким-то вариантом протокола типа дай/возьми.
The God is real, unless declared integer.
Re: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: andyag  
Дата: 06.02.14 18:41
Оценка: 6 (1) +2
Здравствуйте, dimgel, Вы писали:

D>А может и не давненько, да я пропустил.


D>Добрался вот, читаю "O'Reilly RESTful Web Services", ещё тыщу лет назад посоветованную кажется gandjustas'ом. И вот что я хочу сказать:


D>1. Воды — просто фантастическое количество. Тянет на книгу рекордов Гиннесса. Прочитано: 10%; полезного найдено: 1 предложение. А именно (привожу примерно): "RPC выставляет наружу алгоритмы, REST — данные". Сдаётся мне, остальные 90% можно не читать. Рекомендовать такую, прости господи, литературу — это чистый садизм.


Не читал, но осуждаю.

D>2. Из процитированного предложения следует одна простая вещь: с помощью REST можно отредактировать запись в базе, но нельзя, к примеру, отправить email. Нельзя сделать ничего такого, что не является чтением/записью данных.


Видимо, плохая книжка, раз сформировалось такое восприятие. REST в этом своём аспекте требует перехода из базиса действий в базис существительных. Т.е. надо просто немного жерезжопнее думать: вместо "отправить письмо" — "положить письмо в стопку исходящих". Вроде одно и то же, но уже
POST /outbox
{
  "message": "hi there"
}
Начинает выглядеть чуть осмысленнее. Но это вообще не самое то, что REST.

D>3. То есть, если нам надо отправить email, мы либо пуляем RPC поверх HTTP (раз mismatch), либо прикидываемся, что "отправка email" — это типа разновидность записи данных такая (два mismatch). Куда не плюнь — всюду mismatch.

Это примерно такой же mismatch, как вообще говорить "отправить письмо". Там ведь после вашего запроса (будь то RPC или REST) не напишет никто письмо от руки, не пойдёт на почту пооблизывать марки. То что вы делаете — это в любом случае — отправить пачку байтов куда-то там. Просто чтобы крыша не поехала, вы мыслите на другом уровне абстракции. Что вас заставляет думать терминами "отправить письмо", а не "положить письмо в исходящие"?

D>4. Вывод: вот и границы применимости этого вашего REST-а нарисовались: помойки данных, где любые операции, отличные от чтения/записи даных, идут как неявные побочные эффекты.

Нифига. Все операции условно можно разделить на порождающие сущности, удаляющие сущности и изменяющие состояние сущностей. Если с первым и вторым всё довольно тривиально, последнее — более интересно. Один RPC запрос, как правило, изменяет состояние какой-то одной _логической_ сущности. Технически сущность может быть очень сложной — десятки таблиц в базе, файлы какие-то, но _сама логическая сущность_, над которой производится операция — ровно одна. В результате такого запроса у сущности изменяется какой-то аспект состояния. Вот REST предлагает оформлять API именно в виде таких логических сущностей. Т.е. снаружи оно реально будет выглядеть как тупой CRUD для помойки данных, но внутри может этим и не являться (но в большинстве случаев вы правы — да).

Т.е. вместо того, чтобы говорить, например, ConfirmOrder, вы берёте этот самый Order:
{
  "self": "http://porn/123",
  "confirmed": false
}
выставляете ему confirmed: true и отправляете серверу. На основании диффа между состоянием этого Order на сервере и новым состоянием, которое вы прислали, сервер может (если хочет) понять что за операция случилась. Вот эта самая операция — это тот самый RPC, который вам так нравится. Как только операция "распознана", можно творить любой хаос, как если бы у нас действительно был RPC и пользователь дёрнул ConfirmOrder напрямую. Ни в коем случае не говорю, что именно так стоит эту штуку реализовать — это просто переходная модель мира.

Следующий этап после "переходной модели" — не думать о "действиях" вообще, а думать только о просьбах "что-то поменять" у сущности. Т.е. вместо задавания себе вопроса "что я буду делать в ConfirmOrder?" задавать себе вопрос "что я буду делать, когда кто-то хочет поменять подтверждённость заказа?". Этот подход позволяет проще относиться к ситуациям, когда у сущности предлагается поменять не один аттрибут, а несколько за один раз.

// Я вообще не фанат REST — просто смотрю на это всё со стороны и пытаюсь понять зачем этот REST нужен. Пока не понял. Субъективно — не нужен.
Re[20]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 24.02.14 06:35
Оценка: 6 (3)
Здравствуйте, dimgel, Вы писали:

D>Вопрос. Не так давно где-то краем уха я слышал, что в HTTP 2.0 будет форсировано использование SSL, т.е. это будет всегда https. ХЗ сколько в этом правды,


Во-первых, HTTP/1.1 живее всех живых и сейчас, к слову, находится в состоянии "драфты нового комплекта IETF RFC одобрили и после финального редактирования получат регистрацию":

http://datatracker.ietf.org/doc/draft-ietf-httpbis-p1-messaging/
http://datatracker.ietf.org/doc/draft-ietf-httpbis-p2-semantics/
http://datatracker.ietf.org/doc/draft-ietf-httpbis-p4-conditional/
http://datatracker.ietf.org/doc/draft-ietf-httpbis-p5-range/
http://datatracker.ietf.org/doc/draft-ietf-httpbis-p6-cache/
http://datatracker.ietf.org/doc/draft-ietf-httpbis-p7-auth/

Юристы могут поискать различия, я, кроме странностей стиля, ничего быстро не накопал, но и не старался.

Во-вторых, так называемый HTTP/2.0 сейчас в состоянии глубокой беты (первая отсылка на proposed standard в конце этого года), со сломами совместимости с прошлыми версиямии шумной дискуссии во всех кругах на тему "а нафига он такой и можно ли им в принципе заменить существующее", и ответ, скорее всего, что заменить он не может. Что может — это дополнить. Например, подняв соединение по 1.1, сделать ему upgrade до SPDY — да, скорее всего будут позволять. Умение в сервере сразу определять входной протокол — наверно, тоже (по первой ссылке это таки обещают).

В-третьих, самому протоколу это глубоко пофиг — там бинарные фреймы по TCP-like каналу. Скорее всего, эти слухи основаны на одной фразе из википедии:

For use within HTTPS, SPDY needs the TLS extension Next Protocol Negotiation (NPN), thus browser and server support depends on the HTTPS library.


ключевое слово тут "если", то есть "for <use within HTTPS>". Если не within HTTPS, то, соответственно, поддержка HTTPS не нужна.

D>(Кроме того, несколько непонятна эта вот ортогональность авторизации и кеширования. Т.е. на концептуальном уровне разумно, но практически — )


Ну вот пример из моего свежего опыта. Клиент обращается "дай мои объекты" по короткому URL типа /my/objects. Он получает редирект на /objects/id=${his_id} и забирает его содержимое. /my/objects у всех может быть разный. А вот /objects/id=${his_id}, если у читающего вообще есть право их получать — одинаковое. Но мы не знаем заранее, кто может такое получать — он сам, непосредственный начальник, главный шеф или какой-то сотрудник внутренней безопасности (который при этом, в отличие от прочих, может не иметь права получать содержимое объектов). Значит, надо писать "Vary: Authorization".

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

То есть решать это вообще-то серверу и только ему. Главное — не забыть регулировать.
The God is real, unless declared integer.
Re: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: A13x США  
Дата: 06.02.14 17:43
Оценка: 18 (2)
Здравствуйте, dimgel, Вы писали:

D>А может и не давненько, да я пропустил.


D>Добрался вот, читаю "O'Reilly RESTful Web Services", ещё тыщу лет назад посоветованную кажется gandjustas'ом. И вот что я хочу сказать:


D>1. Воды — просто фантастическое количество. Тянет на книгу рекордов Гиннесса. Прочитано: 10%; полезного найдено: 1 предложение. А именно (привожу примерно): "RPC выставляет наружу алгоритмы, REST — данные". Сдаётся мне, остальные 90% можно не читать. Рекомендовать такую, прости господи, литературу — это чистый садизм.


Мне больше понравилась <b>эта книга</b> (или мы говорим об одной и той же)?

D>2. Из процитированного предложения следует одна простая вещь: с помощью REST можно отредактировать запись в базе, но нельзя, к примеру, отправить email. Нельзя сделать ничего такого, что не является чтением/записью данных.


D>3. То есть, если нам надо отправить email, мы либо пуляем RPC поверх HTTP (раз mismatch), либо прикидываемся, что "отправка email" — это типа разновидность записи данных такая (два mismatch). Куда не плюнь — всюду mismatch.


Рест вполне подходит для таких операций. Цитирую

Rule: POST must be used to create a new resource in a collection

... skipped ...

Rule: POST must be used to execute controllers

Clients use the POST method to invoke the function-oriented controller resources. A POST request message may include both headers and a body as inputs to a controller resource’s function.
HTTP designates POST as semantically open-ended. It allows the method to take any action, regardless of its repeatability or side effects. This makes POST the clear choice to be paired with the equally unrestricted controller resources.
Our REST API designs use POST, along with a targeted controller resource, to trigger all operations that cannot be intuitively mapped to one of the other core HTTP methods. In other words, the POST method should not be used to get, store, or delete resources —HTTP already provides specific methods for each of those functions.
HTTP calls the POST request method unsafe and non-idempotent, which means that its outcome is unpredictable and not guaranteed to be repeatable without potentially un- desirable side effects. For example, a resubmitted web form that uses POST might run the risk of double billing a user’s credit card. Controller resources trade a degree of transparency and robustness for the sake of flexibility.
The example below demonstrates how a controller can be executed using the POST request method:
POST /alerts/245743/resend
This is the second use of POST in the design of REST APIs. This use case resembles the fairly common concept of a runtime system’s “PostMessage” mechanism, which allows functions to be invoked across some sort of boundary.

— Chapter 3: Interaction Design with HTTP

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


D>4. Вывод: вот и границы применимости этого вашего REST-а нарисовались: помойки данных, где любые операции, отличные от чтения/записи даных, идут как неявные побочные эффекты.
Re[10]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: fddima  
Дата: 08.02.14 04:43
Оценка: 8 (1) -1
Здравствуйте, dimgel, Вы писали:

F>> PS: POST — есть Create. PUT — есть Update. Реализация идемпотентности к POST (а она нужна) — зависит полностью от тебя, что бы там умы не говорили.

D>В моей исходной цитате PUT предлагалось в качестве add to store. Хочешь сказать, что это не create?
Думаю, что create — всё таки должен быть POST. Хотя PUT, в случае когда id (url) создаваемого ресурса заранее известен — наверное тоже может быть применён. Но я бы так не делал. Да и мне не встречались чужие сервисы которые бы так делали.
CRUD = PGPD (POST — GET — PUT — DELETE)
Re[2]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sinclair Россия https://github.com/evilguest/
Дата: 07.02.14 07:25
Оценка: 6 (2)
Здравствуйте, andyag, Вы писали:

A>// Я вообще не фанат REST — просто смотрю на это всё со стороны и пытаюсь понять зачем этот REST нужен. Пока не понял. Субъективно — не нужен.

Чтобы понять, зачем он нужен, нужно получить негативный опыт на предшествующих технологиях. Когда вы упрётесь в то, что банальный conditional get требует редизайна RPC Endpoint, что означает "давайте лучше не будем, пока перформанс не вызовет эскалацию на уровне нашего директора", вы начнёте понимать, в чём преимущество подхода с safe methods. Когда вы столкнётесь с тем, что прикручивание идемпотентности тоже требует редизайна RPC Endpoint, причём обратно-несовместимым образом, что означает "давайте лучше не будем, пока количество сбоев не вызовет эскалацию на уровне нашего директора", вы поймёте, что REST всего лишь заставляет вас думать о реальности.
Да, приходится втискивать предметную область в непривычные рамки. Но на самом деле никакого mismatch нету — он появляется искусственно, когда сначала предметная область втискивается в рамки RPC. Просто эти рамки привычнее, и для втискивания в них не нужно делать почти никакого усилия. А вот потом, при "перевтискивании" приходится напрягать мозг, и возникает иллюзия какой-то неправильности.

Аналогом может являться представление звукового сигнала. Если привыкнуть представлять его в виде "отсчётов" — измерений амплитуды во времени, то переход к частотному представлению кажется совершенно противоестественным. Типа "ну и как я буду теперь отрезать первые 5 секунд от этой записи?" Зато в частотном представлении становятся удобными другие операции — например, фильтры низких/высоких частот.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[17]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 10.02.14 06:40
Оценка: 3 (1) +1
Здравствуйте, Cyberax, Вы писали:

C>Нет. Враг угадывает какой UUID будет у запроса create_new_user() от привиллегированного пользователя и использует этот UUID при создании пользователя под своим контролем.


Какая-то муть в квадрате.

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

Во-вторых, в описанном алгоритме принципиальная диверсия — временное беззащитное состояние нового пользователя, вместо того, чтобы сразу в запросе создания назначить ему необходимое (или если уж по дефолту, то ставить безопасный минимум).

Если так через одно место проектировать, то у вас это будет минимальной проблемой из всех.

C>Решения:

C>1) Сделать клиентский токен полностью алгоритмическим, включив туда ID пользователя и секретные данные. Так поступает, например, Amazon. Недостаток: сложность реализации, не всякий клиент может иметь доступ ко всем нужным HTTP-заголовкам.
C>2) Серверные тикеты с проверкой авторизации, включая возможность выдать сразу N тикетов.

3) выпрямить руки, pardon my french, и сделать так, чтобы от знания посторонним конкретного id ничего не ломалось.
The God is real, unless declared integer.
Re: И еще забыл. Книги
От: Mamut Швеция http://dmitriid.com
Дата: 24.02.14 15:38
Оценка: 3 (2)
D>Рекомендовать такую, прости господи, литературу — это чистый садизм.

Внятных книг да, очень мало. Могу разве что порекомендовать этот список: http://www.goodreads.com/review/list/22579776-andrei?order=d&amp;shelf=api&amp;sort=rating

Комментарий от автора списка: the most recent and enjoyable book was the asp.net one — not to worry, it has lots of non-.net writings

Много ссылок по теме: https://delicious.com/andrei.neculau/rest


dmitriid.comGitHubLinkedIn
Re: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: avpavlov  
Дата: 06.02.14 13:53
Оценка: +2
D>3. То есть, если нам надо отправить email, мы либо пуляем RPC поверх HTTP (раз mismatch), либо прикидываемся, что "отправка email" — это типа разновидность записи данных такая (два mismatch). Куда не плюнь — всюду mismatch.

Да ну брось. Пусть REST выставляет очередь на отправку емайлов. Операция PUT — помещает в очередь. Никакого мисматча
Re[2]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: vsb Казахстан  
Дата: 07.02.14 00:17
Оценка: +1 :)
Здравствуйте, avpavlov, Вы писали:


D>>3. То есть, если нам надо отправить email, мы либо пуляем RPC поверх HTTP (раз mismatch), либо прикидываемся, что "отправка email" — это типа разновидность записи данных такая (два mismatch). Куда не плюнь — всюду mismatch.


A>Да ну брось. Пусть REST выставляет очередь на отправку емайлов. Операция PUT — помещает в очередь. Никакого мисматча


А можно на примере этой отправки емайлов объяснить — какое преимущество мы получаем от отправки емайла в стиле REST? Недостаток я уже понял, надо думать думу, как вместить тривиальную операцию в ограниченную предметную область. На первый взгляд совершенно ненужная дума, отнимающая время и не дающая никакого преимущества перед лобовой реализовацией post /sendemail { "message": "hello" }.
Re[12]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Cyberax Марс  
Дата: 07.02.14 15:00
Оценка: +1 :)
Здравствуйте, Sinclair, Вы писали:

S>> Кстати а как Идемпотентность решена в RESTE?

S>By design. Спецификация требует, чтобы глаголы PUT и DELETE были идемпотентными. Всё.
Ну то есть: "станьте ёжиками".
Sapienti sat!
Re: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: dimgel Россия https://github.com/dimgel
Дата: 12.02.14 09:33
Оценка: +2
Дожили. В кои-то веки профильную тему завёл — и ту в КСВ перенесли. Пойду нафиг напьюсь.
Re[16]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 10.02.14 16:41
Оценка: 102 (1)
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, Serginio1, Вы писали:


S>> Кстати можешь скинуть ссылку где в MVC прописывать параметры кэширования.

S>Тема сложная, я сходу даже англоязычной статьи про это не нашёл.
S>В том смысле, что тупое кэширование прикручивается статически на атрибутах, но его полезность меньше нуля.

S>А что у вас за задача? Чтобы правильно кэшировать, нужно понимать семантику запроса и ответа. В большинстве случаев, имеющих прикладное значение, нужно не "кэширование", а корректная обработка Conditional GET. Вот с ней, к сожалению, всё более-менее плохо. То есть во времена ASP.NET WebForms вроде бы было приемлемое решение (хотя им так и не научились пользоваться), а что является его аналогом для современного MVC я не в курсе.


Увы нет такого, надо все руками. Наверное потому что http-cache оказывается app specific, так как зависит от способа узнавания были изменения на сервере или нет. А выставить правильные заголовки — дело трех строк, так что нет смысла прикручивать что-то сверху.

У меня статья есть на эту тему, вдруг пригодится: http://gandjustas.blogspot.ru/2013/02/aspnet-mvc.html
Re[15]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 10.02.14 16:37
Оценка: 9 (1)
Здравствуйте, Serginio1, Вы писали:

S>Здравствуйте, Sinclair, Вы писали:


S> Большое спасибо за развернутый ответ. Я сейчас только начал делать сайт на MVC для доступа клиента к своим данным на основании авторизации и забитого в users его ID. И читая эту ветку пришел к ужасу по поводу кэширования.

S> Кстати можешь скинуть ссылку где в MVC прописывать параметры кэширования.
S>http://xmlhack.ru/texts/06/doing-http-caching-right/doing-http-caching-right.html

http://gandjustas.blogspot.ru/2013/02/aspnet-mvc.html
Re[6]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sinclair Россия https://github.com/evilguest/
Дата: 07.02.14 09:53
Оценка: 8 (1)
Здравствуйте, dimgel, Вы писали:

D>Скажи лучше, как тебе такая идейка для отладки RESTful-сервиса: отдавать XML с <?xls-stylesheet?>, чтобы можно было прям настоящее живое API из-под браузера глазками-ручками тестировать. (Вообще, я сильно больше JSON люблю, но тут мне кажется может получиться забавно.)

Отличная идейка. И это никак не противоречит JSON, т.к. руками данные сейчас всё равно никто не клеит, а при наличии инфраструктуры научить сервис использовать разные сериализаторы в зависимости от .html/.xml/.js в конце урла не стоит почти ничего.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[6]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sinclair Россия https://github.com/evilguest/
Дата: 09.02.14 16:43
Оценка: 8 (1)
Здравствуйте, dimgel, Вы писали:
D>А почему добавление в store — PUT, а в collection — POST? Причём изменение ресурса, в т.ч. элемента коллекции — тоже PUT, то нафига тут POST вообще? Если дело в том, что PUT идемпотентный, то может у меня store допускает задвоения экземпляров?
Это трудности перевода. PUT — это не "добавление" в store, это просто запись в хранилище. В то, которое идентифицировано URL, переданным в PUT.
Например,

PUT http://dormitoryservice.nsu.ru/dorm6/314/1 
...

{
  Name='Vasily'
}

— на первой койке в комнате 314 теперь живёт Василий.
POST, если речь о добавлении чего-то — это "вставь куда-нибудь сюда":
PUT http://dormitoryservice.nsu.ru/dorm6/
...

{
  Name='Vasily'
}

Василий будет прописан куда-то на свободное место. Надо понимать, что отсутствие идемпотентности означает, что повторный вызов приведёт к тому, что на Василия будет записано две койки (если не принимать специальных мер). Это радикально отличается от семантики PUT, и даёт нам ключ к пониманию применимости: если мы знаем адрес нового объекта, то нам достаточно PUT. Если адрес должен придумать сервис, то придётся перейти на POST. При этом сразу надо думать о том, как избежать дубликатов в случае сбоев. Обычно это достигается соглашениями типа Primary Key — т.е. добавляем в данные номер паспорта, и в случае повторов отправляем код 4xx, предоставляя клиенту разбираться с тем, почему так получилось. Это несколько усложняет клиента — в случае идемпотентной операции признак успеха — код 2хх, а 4хх означает ошибку. Теперь нам надо внимательно смотреть на код ошибки и разбираться, то ли мы чего-то накосячили и Василий остался без койки, то ли всё уже хорошо, просто в прошлый раз мы этого не поняли.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[13]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sinclair Россия https://github.com/evilguest/
Дата: 09.02.14 16:57
Оценка: 6 (1)
Здравствуйте, dimgel, Вы писали:

D>Эм... А часто ли он известен? Тут как бы по ощущениям подразумевается, что в базе PK — GUID-ы, генерируемые как раз как номера тикетов, так?

Он известен ровно тогда, когда это предусмотрел разработчик протокола
То есть — одно из трёх:
— естественные ключи (рейс-дата-номер места)
— распределённо-генерируемые искусственные ключи (читай — GUID)
— централизованно-генерируемые искусственные ключи (читай — тикеты).

Случаев, когда адрес нового объекта ну совсем-совсем неизвестен, нужно избегать, т.к. они приносят слишком много геморроя.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[13]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sinclair Россия https://github.com/evilguest/
Дата: 10.02.14 07:32
Оценка: 6 (1)
Здравствуйте, Serginio1, Вы писали:
S> Ну вот я отправляю письмо. Должен ему присвоить какой URL в котом содержится ID этого письма, что бы при повторной посылке POST оно не отправлялось, а получался ответ который до меня не дошел.
Всё правильно, только при PUT, а не POST.

S> Так же и с GET если я запрашиваю справочник по ID то согласно idempotent мне по этому ID должен возвращаться всегда одни и теже данные.

Нет. GET — safe, это другое, чем идемпотентность.

S>Согласно этому определению

В русской вики, как обычно, чушь. Читать надо не её, а RFC 2616.

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

Такие проблемы возникают от непонимания протокола HTTP и того, как там работает кэширование.
Нужно выставлять корректные хидеры ответов, и корректно обрабатывать хидеры запросов. Тогда данные будут возвращаться те, что нужно.
S> Тогда я понимаю что бы избавиться от идемпотентности можно добавить GUID или метку времени в строку запроса?
Так делают в специальных случаях: например, т.н. вторичных запросов. Допустим, ваша веб-страница использует некую JavaScript библиотеку. Библиотека изменяется раз в никогда (например, раз в год), причём заранее предсказать дату её изменения невозможно. У вас есть две задачи:
1. Обеспечить максимальную производительность клиента и минимальную нагрузку на сервер, отдающий код библиотеки.
2. Обеспечить как можно более быструю замену библиотеки на клиентах при выходе новой версии
Эти задачи на первый взгляд друг другу противоречат: если поставить длинный expiration, то клиенты будут редко ходить за библиотекой, но при смене версии они продолжат работать с устаревшей. Если поставить короткий expiration (либо вообще положиться на conditional GET), то клиенты будут постоянно долбить сервер.
Решается предельно просто: версия библиотеки вшивается в URL, тело отдаётся с хидерами Expiration:never.
Теперь клиенты никогда не будут перезапрашивать библиотеку, а сразу будут брать её из кэша (экономия roundtrip time — около 100мс — на этапе загрузки страницы). Обновление библиотеки будет мгновенным — как только мастер-страница обновится, она укажет новый адрес библиотеки, и клиент немедленно скачает её в кэш.

Для первичных запросов такая техника не очень подходит. Дело в том, что при длинной экспирации нужен механизм оповещения об устаревании кэша. Во вторичных запросах механизм опирается на изменение src в основной странице, поэтому он прекрасно подходит для стилей, картинок, и скриптов. А для самой страницы такого механизма нет. То есть можно сделать мат в два хода: например, при запросе http://news.com/latest возвращать 302 Found на "последнюю" новость, отдавая location типа: http://news.com/2014/02/10/1788/.
Увы:
1. Большинство браузеров поменяют URL текущей страницы на переданный, так что последовательное нажатие F5 уже никогда не обновит страницу
2. При обновлении новостей придётся делать два запроса — что хуже, чем один с conditional get.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[15]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sinclair Россия https://github.com/evilguest/
Дата: 10.02.14 10:08
Оценка: 6 (1)
Здравствуйте, Serginio1, Вы писали:

S> Кстати можешь скинуть ссылку где в MVC прописывать параметры кэширования.

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

А что у вас за задача? Чтобы правильно кэшировать, нужно понимать семантику запроса и ответа. В большинстве случаев, имеющих прикладное значение, нужно не "кэширование", а корректная обработка Conditional GET. Вот с ней, к сожалению, всё более-менее плохо. То есть во времена ASP.NET WebForms вроде бы было приемлемое решение (хотя им так и не научились пользоваться), а что является его аналогом для современного MVC я не в курсе.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[3]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sinclair Россия https://github.com/evilguest/
Дата: 07.02.14 07:11
Оценка: 4 (1)
Здравствуйте, dimgel, Вы писали:
D>Как идемпотентность этого PUT обеспечивать будешь? Если он выдан дважды, может это два одинаковых письма отправить надо?
Вот как раз в отличие от корявого RPC, то, что вы задались этим вопросом сейчас (а не через 6 месяцев эксплуатации), гарантирует вашим клиентам спокойный ночной сон.
Есть два очевидных сценария:
1. Client-generated IDs. То есть я генерирую GUID и использую его при постановке в очередь.
2. Server-generated tickets. To есть я запрашиваю ID у сервера при помощи POST на соответствующий ресурс, а потом использую его в PUT.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[7]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sharov Россия  
Дата: 07.02.14 10:19
Оценка: 4 (1)
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, dimgel, Вы писали:


D>>Скажи лучше, как тебе такая идейка для отладки RESTful-сервиса: отдавать XML с <?xls-stylesheet?>, чтобы можно было прям настоящее живое API из-под браузера глазками-ручками тестировать. (Вообще, я сильно больше JSON люблю, но тут мне кажется может получиться забавно.)

S>Отличная идейка. И это никак не противоречит JSON, т.к. руками данные сейчас всё равно никто не клеит, а при наличии инфраструктуры научить сервис использовать разные сериализаторы в зависимости от .html/.xml/.js в конце урла не стоит почти ничего.

Ребят, обожите. Если я правильно понял ваши идеи, то сейчас этих тестировщиков REST API
навалом. Есть плагины для фф и для хрома. Fiddler опять же...
В чем прикол?
Кодом людям нужно помогать!
Re[9]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sinclair Россия https://github.com/evilguest/
Дата: 07.02.14 13:39
Оценка: 4 (1)
Здравствуйте, dimgel, Вы писали:
D>А во-вторых, в порекомендованной A13X-ом книге (в начале, до подробностей в главе про тело ответа не добрался ещё) что-то говорилось про передачу ссылок на связанные документы в составе ответа. Т.е. с помощью ссылок (игнорируемых программным клиентом) и XSLT можно очень удобную фигню замутить, с полноценной навигацией.
Не, вот как раз игнорировать ничего не надо. Весь REST построен как раз на адресуемости объектов.
То есть вместо возврата непрозрачных идентификаторов, которые нужно как-то угадать куда вставлять, в ресте рекомендуется возвращать прямо честные URL, по которым можно сделать GET (ну, или другие глаголы).
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[11]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sinclair Россия https://github.com/evilguest/
Дата: 07.02.14 14:34
Оценка: 4 (1)
Здравствуйте, Serginio1, Вы писали:
S> Поиск не работает.
Зачем поиск? В этой теме не так много постов.

S> Мне интересно как на физическом уровне. Понятно, что должно где то храниться ID запроса. И насколько это накладно для всех видов запросов.

Нет никакого ID запроса. У каждого объекта есть URL. Операции с объектом делятся на safe, idempotent, и операцию POST. Поэтому ничего "отдельно" хранить не надо.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[14]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sinclair Россия https://github.com/evilguest/
Дата: 09.02.14 17:06
Оценка: 4 (1)
Здравствуйте, dimgel, Вы писали:
D>Хотя GUID-ы клиент и сам генерить может. А если подсунет левый и что-нибудь из доступных ему на запись данных сломает, тут уж звиняйте, ССЗБ.
Да. Основное преимущество GUID-ов — в том, что их можно генерировать полностью локально. "Подсовывание левого" является неотъемлемым правом клиента. Если он решил всю свою коллекцию порнухи сохранить под одним и тем же гуидом, то и флаг ему в руки — как мы отличим его от легитимного "ой, нет, я лучше сюда другой фильм закачаю"?
А с правами доступа разобраться достаточно легко. Если для конкретного клиента можно выделить песочницу — так и делаем, конфликты игнорируем. Т.е. я пишу в .../sinclair/001/ одно, вы — в .../dimgel/001/ другое, и мы друг другу никак не мешаем. Если я могу дать права dimgel на запись в /sinclair, то уже нужно тщательнее следить за руками. GUID хорош тем, что случайно получить такой же, как у соседа, невозможно. То есть вы должны сначала как-то подсмотреть один из существующих GUIDов в моей песочнице, и уже потом чего-то туда писать.

Если используются не GUID, а что-то с большей вероятностью конфликтов, или если нам важно избежать случайной перезаписи чужих изменений, то в REST есть специальный паттерн "Версионирование". Т.е. читать я могу из /sinclair/001/ (получу 301 на /sinclair/001/0011, где 0011 — номер последней версии), а вот записывать надо в /sinclair/001/0012/, где 0012 — это номер новой версии. Если такая версия уже есть, то я получаю 409 Conflict — это означает, что кто-то успел вклиниться между моими чтением и записью. Обычно это повод перечитать объект, и начать принятие решения с нуля — может быть, версия 0012 от конкурента лучше, чем то, что я хотел в неё записать.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[16]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Cyberax Марс  
Дата: 10.02.14 06:32
Оценка: 4 (1)
Здравствуйте, Sinclair, Вы писали:

S>>>Да хоть 1000 — принцип тот же.

C>>Ну да, то есть никакого.
S>Что значит "никакого"? Принцип — делаем PUT в объект "Transaction".
Сотню запросов с латентностью в 200-300 миллисекунд? Ну-ну.

C>>Оказалось нужно различить PUT с дефолтными значениями и PATCH изменившихся.

S>Не до конца понимаю. Это же ваш протокол, что мешало внести в него понятия (reset-to-default), (clear), (leave-as-is) в дополнение к установке конкретного значения?
Код библиотеки на JS так не умеет.

C>>Если враг может сделать так, что для create_new_user() будет конфликт UUID'ов, то есть шанс подменить user_id на контролируемый врагом.

S>Продолжаю не понимать. То есть вы хотите сказать, что клиент 1 (привилегированный) делает типа assign_roles(admin_role), а клиент 2 (непривилегированный) делает reset_password(), и всё это на один и тот же user_id?
Нет. Враг угадывает какой UUID будет у запроса create_new_user() от привиллегированного пользователя и использует этот UUID при создании пользователя под своим контролем.

Затем привиллегированный пользователь делает create_new_user() с этим же UUID'ом и ему попадает уже существующий пользователь, которого создал враг, так как для сервера это кажется просто повторением запроса из-за ошибки клиента.

Ну и дальнейшая эксплуатация может быть разной.

Решения:
1) Сделать клиентский токен полностью алгоритмическим, включив туда ID пользователя и секретные данные. Так поступает, например, Amazon. Недостаток: сложность реализации, не всякий клиент может иметь доступ ко всем нужным HTTP-заголовкам.
2) Серверные тикеты с проверкой авторизации, включая возможность выдать сразу N тикетов.
Sapienti sat!
Re[8]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sinclair Россия https://github.com/evilguest/
Дата: 07.02.14 10:23
Оценка: 3 (1)
Здравствуйте, Sharov, Вы писали:
S>Ребят, обожите. Если я правильно понял ваши идеи, то сейчас этих тестировщиков REST API
S>навалом. Есть плагины для фф и для хрома. Fiddler опять же...
S>В чем прикол?
Прикол в том, что быстрее всего просто зайти браузером в URL и "пощупать руками", и "посмотреть глазами".
Вот, например, http://apscatalog.com/2.0/
Это API нашего каталога — он полностью browser discoverable. Но выглядит страшненько без стилей. Лучше делать view source, но это неудобно — во view source нет навигации по кликам.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[11]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sinclair Россия https://github.com/evilguest/
Дата: 07.02.14 14:32
Оценка: 3 (1)
Здравствуйте, Serginio1, Вы писали:
S> Кстати а как Идемпотентность решена в RESTE?
By design. Спецификация требует, чтобы глаголы PUT и DELETE были идемпотентными. Всё.

S> Да мне глубоко по барабану сколько и что весит пока это работает быстро и быстро разрабатывается. А вот когда будут тормоза я наплюю на сложность и я начну оптимизировать усложняя клиентскую часть.

Когда будут тормоза, будет уже поздно. Сейчас Microsoft заменяет SOAP-based API к Office 365 на REST-based Graph API. Разница в скорости видна невооружённым глазом.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[18]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 23.06.14 07:24
Оценка: 3 (1)
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, gandjustas, Вы писали:


G>>У меня статья есть на эту тему, вдруг пригодится: http://gandjustas.blogspot.ru/2013/02/aspnet-mvc.html

S>Отличная статья. Если я правильно понимаю, то подразумеваемый способ борьбы с conditional Get всё же другой.
S>У тебя идёт ручное управление кэшированием: ты кладёшь ответ в кэш вручную, и вручную же проверяешь, что там не так.
S>В теории, вся семантика последующей работы с кэшем уже реализована в самом ASP.NET.
S>То есть, достаточно выставить респонсу подходящий cacheability, зарегистрировать зависимости в response.AddCacheDependency() (например, зависимость от результата SQL-запроса), и всё будет работать само.
S>Логика — примерно такая: если приходит запрос на URL, который уже есть в кэше ASP.NET, то кэш его проверяет на предмет валидности, дёргая HasChanged у всех депенденсей, и если всё в порядке, то отдаёт ответ из кэша, не вызывая код контроллера. А если в запросе присутствует If-Modified-Since, то он ещё и отдаёт 304 вместо контента.

S>К сожалению, на практике я так и не дошёл до полной реализации этого подхода. Если нет подводных камней, то код твоего метода CartSummary должен сократиться в разы.


Таки написал статью по этому http://habrahabr.ru/post/227129/
Re[6]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Ночной Смотрящий Россия  
Дата: 16.02.14 22:01
Оценка: 2 (1)
Здравствуйте, dimgel, Вы писали:

D>Скажи лучше, как тебе такая идейка для отладки RESTful-сервиса: отдавать XML с <?xls-stylesheet?>, чтобы можно было прям настоящее живое API из-под браузера глазками-ручками тестировать.


Можно, но смысла не очень много. Все равно лучше специальный клиент накидать. Я, к примеру, обычно на коленке пишу на дотнете с обычным HttpWebRequest. Дешево и сердито. Можно потом и к автоматичным интеграционным тестам подцепить, и тех разработчиков кто сервисом пользуется пятачком ткнуть (у них любая проблема сразу же означает, что "что то с сервисом не так", хотя в 90% случаев косяки у них).
Re: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Mamut Швеция http://dmitriid.com
Дата: 24.02.14 14:27
Оценка: 2 (1)
D>2. Из процитированного предложения следует одна простая вещь: с помощью REST можно отредактировать запись в базе, но нельзя, к примеру, отправить email. Нельзя сделать ничего такого, что не является чтением/записью данных.

D>3. То есть, если нам надо отправить email, мы либо пуляем RPC поверх HTTP (раз mismatch), либо прикидываемся, что "отправка email" — это типа разновидность записи данных такая (два mismatch). Куда не плюнь — всюду mismatch.


Добавлю (см. N3 и N4 на диаграмме):

Чем отправка email'а принципиально отличается от записи данных? Ничем Потому что в подавляющем большинстве случаев мы не отправляем email, а складируем его в очередь sendmail'а какого-нибудь.

POST /internal/emails
> Content-Type: application/vnd.mega.spam.email-v1+json
{
  "to": ["email1", "email2", "email3"],
  "from": "ceo@paipal.com",
  "subject": "Claim your prize",
  "body": "Claim your prize...",
}


Возможные ответы:
Если обработка прошла сразу
< 201
< Location: /internal/emails/230


Если просто поставили в очередь
< 202
< Location: /internal/emails/230/status


Во втором случае:
-- письмо все еще в очереди
GET /internal/emails/230/status
< 202
< Location: /internal/emails/230/status

-- письмо уже обработано
GET /internal/emails/230/status
< 201
< Location: /internal/emails/230


Пока письмо еще в очереди, попытка его получить:
GET /internal/emails/230
> Accept: application/vnd.mega.spam.email.informational-v1+json
< 404


Когда письмо уже обработано:
GET /internal/emails/230
> Accept: application/vnd.mega.spam.email.informational-v1+json
< Content-Type: application/vnd.mega.spam.email.informational-v1+json
< 200
{
  "status": "delivered",
  "delivery_time": "2014-02-23T23:45:39+00:00"
}


dmitriid.comGitHubLinkedIn
Re[9]: know-your-http-well
От: Mamut Швеция http://dmitriid.com
Дата: 24.02.14 15:53
Оценка: 2 (1)
M>>Смотря, что ты имеешь в виду под генератором REST API

D>Понятия не имею. Но успел увидеть краем уха, что такие бывают. Мне надо хоть от чего-то оттолкнуться.


Мы лопатим вручную По-моему, что-то есть для Java, но увы, не знаю

Обычно все упирается не в генерацию API, а в его дизайн и документацию, для этого http://apiary.io непревзойден и, может быть, еще https://helloreverb.com/developers/swagger

Обычно после дизайна налопатить реализацию несложно, особенно с каким-нибудь Jersey.

Может еще кто что подскажет.


dmitriid.comGitHubLinkedIn
Re[8]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Mamut Швеция http://dmitriid.com
Дата: 09.03.14 10:49
Оценка: 2 (1)
LD>>>Тогда не в порядке спора и попыток переубедить. Объясните как реализовать с помощью REST процедуру логона. Ну точнее не реализовать, а какие API (ресурсы должны быть).
M>>Ну, что-то в такое (писал после бессонной ночи на коленке, и вообще лучше посмотреть на OAuth, например, который что-то подобное реализует)

D>Чёт я недопонял, зачем в REST API отдельная точка входа для login.


При желании можно сделать (для реализации OpenID/OAuth, например, отдельная точка входа все равно будет). Отдельная точка входа REST'у не противоречит


dmitriid.comGitHubLinkedIn
[давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: dimgel Россия https://github.com/dimgel
Дата: 06.02.14 13:26
Оценка: 1 (1)
А может и не давненько, да я пропустил.

Добрался вот, читаю "O'Reilly RESTful Web Services", ещё тыщу лет назад посоветованную кажется gandjustas'ом. И вот что я хочу сказать:

1. Воды — просто фантастическое количество. Тянет на книгу рекордов Гиннесса. Прочитано: 10%; полезного найдено: 1 предложение. А именно (привожу примерно): "RPC выставляет наружу алгоритмы, REST — данные". Сдаётся мне, остальные 90% можно не читать. Рекомендовать такую, прости господи, литературу — это чистый садизм.

2. Из процитированного предложения следует одна простая вещь: с помощью REST можно отредактировать запись в базе, но нельзя, к примеру, отправить email. Нельзя сделать ничего такого, что не является чтением/записью данных.

3. То есть, если нам надо отправить email, мы либо пуляем RPC поверх HTTP (раз mismatch), либо прикидываемся, что "отправка email" — это типа разновидность записи данных такая (два mismatch). Куда не плюнь — всюду mismatch.

4. Вывод: вот и границы применимости этого вашего REST-а нарисовались: помойки данных, где любые операции, отличные от чтения/записи даных, идут как неявные побочные эффекты.
Re[3]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sinclair Россия https://github.com/evilguest/
Дата: 07.02.14 07:14
Оценка: 1 (1)
Здравствуйте, vsb, Вы писали:
vsb>А можно на примере этой отправки емайлов объяснить — какое преимущество мы получаем от отправки емайла в стиле REST?
Очень простое — предсказуемость работы в случае сбоев. Если RPC вызов "SendMail" упал по таймауту или вернул 5хх, то нет никакого способа узнать, было ли письмо таки отправлено. Retry, возможно, приведёт к дублированию (и я раз в иногда получаю пару десятков писем от залипшего клиента), а игнор, возможно, приведёт к потере. REST позволяет мне Retry-ить в случае сомнений до получения либо 2хх либо 4хх.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[7]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sinclair Россия https://github.com/evilguest/
Дата: 07.02.14 11:07
Оценка: 1 (1)
Здравствуйте, netch80, Вы писали:

N>Здравствуйте, avpavlov, Вы писали:


N>>>Вы отвечаете, даже не попытавшись понять суть проблемы. Пусть передача тела по PUT завершилась, а перед получением OK от сервера порвалась связь. Как клиент поймёт, передавать заново или нет?

A>>Почему она только для РЕСТ "нерешаема"?

N>Она решаема. С разной степенью надёжности в зависимости от применённых средств. Но Ваш метод точно её не решит.

Она решаема в REST со стопроцентной надёжностью. Клиент прекрасно понимает, передавать заново или нет: если он получил таймаут, или 5xx, то нужно повторять. Если 3xx, то нужно повторять с другим target URL, который можно получить из тела или заголовков ответа. Если 4xx, то нужно вернуть статус "не проконало" на уровень выше, т.к. данных для самостоятельного принятия решения недостаточно. И только если мы получаем 2xx, мы понимаем, что всё получилось успешно.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[23]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sinclair Россия https://github.com/evilguest/
Дата: 10.02.14 09:10
Оценка: 1 (1)
Здравствуйте, Cyberax, Вы писали:

C>Так нету буквы R — Representational. Обычный RPC есть.

C чего это нету?

C>Оно руками реализуется в несколько строк (на клиенте).

А можно убедительную ссылку?

C>У нас модель такая — на нашей платформе пишутся приложения, мы приложениям даём API.

И? Как это противоречит отдаче JavaScript Client Library?

C>Читал. Извиняюсь, что не заметил пример с криптостойким ID — он потерялся на фоне уязвимых примеров.

C>Math.random() угадывается из соседней вкладки браузера, например.
Не понимаю. Можно подробнее? Вы предполагаете, что идиот-пользователь откроет параллельно со страничкой клиента, написанной идиотом-программистом, страничку, написанную злоумышленником? И при этом есть какая-то уязвимость в виде XSS, которая позволит злой страничке взаимодействовать с доброй?
Интересно.

C>И подмешивание timestamp'а не решает ничего, так как идентификаторов можно насоздавать заранее тонну.

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

C>У Amazon'а примерно такой API есть — его неправильно использовать просто нельзя.

REST?

C>Такими темпами сброс прав надо на каждую операцию будет делать.

Пока причин так делать не видно. Сброс прав при создании нового объекта — вполне естественная вещь, и я не понимаю, почему она вызывает какие-либо проблемы. Сброс прав при переводе несекретного объекта в секретный — минимальное требование безопасности. Во всех остальных случаях (внесение изменений в объект) я не вижу ни самой проблемы, ни её специфики для REST.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[9]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sinclair Россия https://github.com/evilguest/
Дата: 07.02.14 13:32
Оценка: +1
Здравствуйте, Serginio1, Вы писали:

S>Прикручивать приходится потому, что 1С не поддерживает все возможности. Да понятие неприлично дорогое для меня непонятно, это пшик (2-3 строчки)по сравнению с реально написанным кодом)

Этот пшик требует канала обратного вызова, что вообще говоря нонсенс в современном мире. То, что за вас кто-то написал тонну говнокода, который занимается нагреванием атмосферы, не отменяет технического убожества этого решения.
Надо смотреть в корень: единственным способом борьбы с отказами в распределённой системе является идемпотентность. REST, как подход, ставит эту идемпотентность на важное место и уделяет ей должное внимание. А SOAP начинает с отказа от идемпотентности, а потом придумывает себе адски сложные и дорогие в эксплуатации надстройки для возврата идемпотентности туда, где её не было.

S> Но вот в большинстве то используют SOAP потому, что его легко использовать.

Его легко использовать не потому, что он хороший, а потому, что к моменту выхода REST на сцену в SOAP уже были вбуханы миллиарды. Это как ездить в "киоск во дворе" на джипе: адски неэффективно "под капотом", но если у вас уже есть корпоративный джип, то вы таки будете им пользоваться даже для этого. А вот предлагать купить джип ради поездок за бутылкой пива на расстояние в 80 метров и обратно — это, простите, долбоклюйство.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[3]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: -n1l-  
Дата: 07.02.14 16:14
Оценка: :)
Очень просто. То приложение в котором пользователи участвуют лишь косвенно и отслеживание состояния какой либо сущности не важно.
Так как email уже упомянули, я назову сервис (проверки)диагностики чего-нибудь например: скорости интернета, карты, показания датчиков online, какие-то расчеты.
Тут дело не в том, что типов проектов в которых REST не нужен — нет, а дело в том, что проектов по одному, двум типам в которых REST нужен — море.
Вот и создается впечатление,что REST основа всего и вся, что без нее никуда, что нужно постоянно в ней практиковаться и улучшать ее, но в итоге все равно припрется какой-нибудь умник, достанет из чулана xml-rpc, cgi, приправит это все каким-нибудь ruby, сделает gem и автогенерацию кода, напишет унылую статью на хабрахабр с заголовком "REST устарел встречайте бла-бла-бла..." или "Вы все еще используете REST?" или "Недостатки REST и как мы все с этим жили", потом это все обмусолится на какой-то еще более унылой конференции для корпораций в сфере айти. Далее в эту клоаку нырнут наивные работодатели и студентики, думая: "вау, новые технологии их надо изучать их нужно внедрять и развиваться", и в итоге все то, что решалось с помощью REST будет решаться с помощью вот той фигни.
Если я непонятно выразился, то объясню чуть популярнее. Какая вам разница, по какой методике изготавливают холодильник, в котором вы храните еду, если он исправно работает? Да никакой. Избыток технологий создал ситуацию в которой вы можете выбирать как, что и каким образом вы будете создавать.
Это делает сами споры о том, какая технология лучше просто абсурдными и бессмысленными. А факт попытки убеждения кого-либо, в том, что какая-то технология/архитектура/<что-то еще> лучше(просто лучше, не лучше подойдет для задачи, а просто лучше), можно интерпретировать, как симптом разложения головного мозга.
Re[8]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: fddima  
Дата: 08.02.14 04:24
Оценка: -1
Здравствуйте, dimgel, Вы писали:

D>Да в общем-то я спрашивал про совершенно конкретный сугубо утилитарный момент, чтобы не сделать по-своему и не вляпаться в непонимание клиентских реализаций. Когда задаёшь вопрос "как на жаве сложить 2+2", ожидаешь ответ-таки по существу, а не в духе "жава — всего лишь один из языков, и не обязательно самый лучший, и сложение во всех языках есть". Про философию эту все и так более-менее в курсе.

Про философию тут то в курсе все, но, я вот вляпался в непонимание сервером JSON. Стоит ли мне рассчитывать, что сервер в действительности удовлетворяет допустим, свойству идемпотентности некоторых методов? Выглядит как REST. И что мне это даёт? Да ничего не даёт. Он всё так же может, а может и нет.
Я всегда думал о вызове методов HTTP сервера как о RPC, и буду думать так. И потому, что это ни, что иное как RPC и есть. RPC кстати не обязан ходить по какому-то определённому протоколу.
Я в большей степени по этому и удивлён каким-то этим спорам, когда сравнивается одна фундаментальная вещь (RPC) с модно-конкретной (REST).

PS: POST — есть Create. PUT — есть Update. Реализация идемпотентности к POST (а она нужна) — зависит полностью от тебя, что бы там умы не говорили.
Re[11]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 08.02.14 10:56
Оценка: +1
Здравствуйте, fddima, Вы писали:

F> Думаю, что create — всё таки должен быть POST. Хотя PUT, в случае когда id (url) создаваемого ресурса заранее известен — наверное тоже может быть применён. Но я бы так не делал. Да и мне не встречались чужие сервисы которые бы так делали.

F> CRUD = PGPD (POST — GET — PUT — DELETE)

Мы делаем. Нет никакой проблемы разрешить клиенту генерировать uuid, когда есть разделение прав и явное указание создать.
The God is real, unless declared integer.
Re[19]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: dimgel Россия https://github.com/dimgel
Дата: 10.02.14 07:18
Оценка: +1
Здравствуйте, Cyberax, Вы писали:

C>Типичный способ реализации идемпотентности с минимальными расходами — в БД записываем client UUID в поле в таблицу user, так что всё прекрасно сломается.


Эм... Мне кажется, этот способ глючный сам по себе: два одновременных одинаковых запроса (хотя бы с разных табов браузера) всё положат. Я тут обмозговываю полученную информацию, и прихожу к выводу, что если я не хочу GUID-ы в качестве PK, то остаётся только server-side генерация тикетов, причём отдельный журнальчик хранить — кому и для какой операции какой тикет сгенерирован. И подчищать в нём старые записи.
Re[4]: know-your-http-well
От: dimgel Россия https://github.com/dimgel
Дата: 24.02.14 08:52
Оценка: +1
Здравствуйте, Mamut, Вы писали:

M>Это только так кажется.

M>Вот именно поэтому только doGet и прочими не обойтись. Даже составление и обработка грамотного ETag'а — это уже больше, чем просто doGet()

Возможно. Я планирую плотно заняться обдумыванием генератора REST API (с предварительным ковырянием в чужих, и может даже O'Relly придётся дочитать, т.к. пока что не понятно ни черта) не раньше чем через месяц. А одну книжку осилил заранее, чтобы пока что в фоновом режиме хоть что-то утряслось.
Re: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sharov Россия  
Дата: 06.02.14 13:58
Оценка:
Здравствуйте, dimgel, Вы писали:

Относительно недавно срач
Автор: TYuD
Дата: 22.12.12
был.

D>Добрался вот, читаю "O'Reilly RESTful Web Services", ещё тыщу лет назад посоветованную кажется gandjustas'ом. И вот что я хочу сказать:


D>1. Воды — просто фантастическое количество. Тянет на книгу рекордов Гиннесса. Прочитано: 10%; полезного найдено: 1 предложение. А именно (привожу примерно): "RPC выставляет наружу алгоритмы, REST — данные". Сдаётся мне, остальные 90% можно не читать. Рекомендовать такую, прости господи, литературу — это чистый садизм.


Так это у любой книги по технологиям так.

D>2. Из процитированного предложения следует одна простая вещь: с помощью REST можно отредактировать запись в базе, но нельзя, к примеру, отправить email. Нельзя сделать ничего такого, что не является чтением/записью данных.


D>3. То есть, если нам надо отправить email, мы либо пуляем RPC поверх HTTP (раз mismatch), либо прикидываемся, что "отправка email" — это типа разновидность записи данных такая (два mismatch). Куда не плюнь — всюду mismatch.


D>4. Вывод: вот и границы применимости этого вашего REST-а нарисовались: помойки данных, где любые операции, отличные от чтения/записи даных, идут как неявные побочные эффекты.


Вроде весь пользовательский веб (блоги, соц. сети) в эту модель удачно укладывается.
Бизнесу rpc поудобнее будет.
Кодом людям нужно помогать!
Re[2]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: dimgel Россия https://github.com/dimgel
Дата: 06.02.14 23:19
Оценка:
Здравствуйте, avpavlov, Вы писали:

A>Да ну брось. Пусть REST выставляет очередь на отправку емайлов. Операция PUT — помещает в очередь. Никакого мисматча


Как идемпотентность этого PUT обеспечивать будешь? Если он выдан дважды, может это два одинаковых письма отправить надо?
Re[2]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: dimgel Россия https://github.com/dimgel
Дата: 06.02.14 23:51
Оценка:
Здравствуйте, A13x, Вы писали:

A>Мне больше понравилась <b>эта книга</b> (или мы говорим об одной и той же)?


Нет, это другая, и тут воды нет. Спасибо.

A>

A>Rule: POST must be used to execute controllers
...
A>HTTP calls the POST request method unsafe and non-idempotent, which means that its outcome is unpredictable and not guaranteed to be repeatable without potentially un- desirable side effects. For example, a resubmitted web form that uses POST might run the risk of double billing a user’s credit card. Controller resources trade a degree of transparency and robustness for the sake of flexibility.s functions to be invoked across some sort of boundary.


A>Таким образом следуя рекомендациям вполне можно сделать и отправку писем и все остальное подобное, имеющее побочные эффекты


Ага... Вот она, реальная жизнь, а не та красивая концептуальщина, про которую тут отдельные товарищи заливали. Но дочитаю-ка сначала. Тут и страниц поменьше в 4 раза будет, и смысла побольше.
Re[2]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: dimgel Россия https://github.com/dimgel
Дата: 07.02.14 00:04
Оценка:
Здравствуйте, andyag, Вы писали:

A>Т.е. надо просто немного жерезжопнее думать


Это тоже paradigm mismatch, между прочим. UPD. Вернее не "тоже", а один из двух, упомянутых мною в исходном сообщении.
Re[3]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: dimgel Россия https://github.com/dimgel
Дата: 07.02.14 00:20
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>Недостаток я уже понял, надо думать думу, как вместить тривиальную операцию в ограниченную предметную область.


Позволю себе поправочку: "в ограниченный набор глаголов".
Re[3]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: dimgel Россия https://github.com/dimgel
Дата: 07.02.14 01:55
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>А можно на примере этой отправки емайлов объяснить — какое преимущество мы получаем от отправки емайла в стиле REST? Недостаток я уже понял, надо думать думу, как вместить тривиальную операцию в ограниченную предметную область. На первый взгляд совершенно ненужная дума, отнимающая время и не дающая никакого преимущества перед лобовой реализовацией post /sendemail { "message": "hello" }.


Обще-теоретический ответ, очевидно, такой: подгонкой своего API под архитектуру веба ты получаешь все плюшки этой архитектуры, в т.ч. масштабируемость и не-велосипедность (принципы архитектуры хорошо перечислены в посоветованной чуть выше
Автор: A13x
Дата: 06.02.14
книге.). А сугубо практически, если следовать рекомендации и завести отдельный поддомен api, то пока что неясно, чем плох /sendmail. Может и ничем, отдельный архетип ресурса — Controller — на это уже намекает (впрочем, тогда уж по идее лучше controller/method, т.е. mailer/send), читаю дальше.
Re[4]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: dimgel Россия https://github.com/dimgel
Дата: 07.02.14 02:00
Оценка:
Здравствуйте, dimgel, Вы писали:

D>отдельный архетип ресурса — Controller — на это уже намекает (впрочем, тогда уж по идее лучше controller/method, т.е. mailer/send), читаю дальше.


А дальше — странное. Предлагается URL такой: /message/ID/send (в книге — "POST /alerts/245743/resend"). Т.е. rich domain model по сути. Не согласная я.
Re[4]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: dimgel Россия https://github.com/dimgel
Дата: 07.02.14 07:29
Оценка:
Здравствуйте, Sinclair, Вы писали:

D>>Как идемпотентность этого PUT обеспечивать будешь? Если он выдан дважды, может это два одинаковых письма отправить надо?


S>Вот как раз в отличие от корявого RPC, то, что вы задались этим вопросом сейчас (а не через 6 месяцев эксплуатации), гарантирует вашим клиентам спокойный ночной сон.

S>Есть два очевидных сценария:
S>1. Client-generated IDs. То есть я генерирую GUID и использую его при постановке в очередь.
S>2. Server-generated tickets. To есть я запрашиваю ID у сервера при помощи POST на соответствующий ресурс, а потом использую его в PUT.

Хоть это и будет "опять двадцать пять" для продолжения беседы, но повторю сказанное ещё в прошлый срач, в котором я участвовал: генерить ID-ы я точно так же и в RPC могу, both корявый RPC and не-корявый REST тут ортогональны. То есть, (опять-таки повторяю тогдашний тезис) "идемпотентость надо обеспечивать руками". По крайней мере для Controller и для Create.
Re[3]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: dimgel Россия https://github.com/dimgel
Дата: 07.02.14 07:34
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Да, приходится втискивать предметную область в непривычные рамки. Но на самом деле никакого mismatch нету — он появляется искусственно, когда сначала предметная область втискивается в рамки RPC. Просто эти рамки привычнее, и для втискивания в них не нужно делать почти никакого усилия. А вот потом, при "перевтискивании" приходится напрягать мозг, и возникает иллюзия какой-то неправильности.


Любопытно и доля истины ощущается. Но ограниченность множества глаголов — объективный факт. (Я ХЗ как ты относишься к типу ресурса "контроллер", мне же он кажется натягиванием презерватива на глобус — отход от концептуально правильного REST-а, пригодного в чистом виде — повторюсь — только для ресурсопомоек, в угоду суровой правде жизни.)
Re: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sinclair Россия https://github.com/evilguest/
Дата: 07.02.14 07:36
Оценка:
Здравствуйте, dimgel, Вы писали:

D>А может и не давненько, да я пропустил.


D>Добрался вот, читаю "O'Reilly RESTful Web Services", ещё тыщу лет назад посоветованную кажется gandjustas'ом. И вот что я хочу сказать:


D>1. Воды — просто фантастическое количество. Тянет на книгу рекордов Гиннесса. Прочитано: 10%; полезного найдено: 1 предложение. А именно (привожу примерно): "RPC выставляет наружу алгоритмы, REST — данные". Сдаётся мне, остальные 90% можно не читать. Рекомендовать такую, прости господи, литературу — это чистый садизм.

Без этой литературы вы, к сожалению, ничего не поймёте. Чтобы эта фраза обрела смысл, нужно налить много воды: несколько раз объяснить простые, вроде бы, вещи; привести несколько десятков примеров. И только после этого в голове может что-то щёлкнуть, и детальки встанут на свои места.

D>2. Из процитированного предложения следует одна простая вещь: с помощью REST можно отредактировать запись в базе, но нельзя, к примеру, отправить email. Нельзя сделать ничего такого, что не является чтением/записью данных.

Вот видите — вы уже начали неправильно понимать. Нет такого следствия. Это как считать "с помощью RPC можно отправить email, но нельзя, к примеру, отредактировать запись в базе". Выразительность и в REST и в RPC совершенно одинакова. Просто в REST больше внимания уделяется опциональным и непопулярным в RPC вещам, что обычно приводит к более высокому качеству протоколов, спроектированных через REST.

D>4. Вывод: вот и границы применимости этого вашего REST-а нарисовались: помойки данных, где любые операции, отличные от чтения/записи даных, идут как неявные побочные эффекты.

Всё наоборот: границы применимости RPC — это бесконечно широкие и бесконечно надёжные каналы связи между клиентом и сервером. Потому что RPC не предлагает никаких возможностей для оптимизации запросов и восстановления после сбоев. А возможности, вшитые в HTTP с прошлого века, требуют приделывания смешных велосипедов. Вот, недавно обнаружил — Windows PowerShell for Windows Azure AD (естественно) внутри использует классический SOAP; при этом нагрузка балансируется на три разных сервера, и делается это при помощи бросания специального исключения "RedirectResponseFault". Пацаны молодцы — всего в нескольких килобайтах кода они прикрутили поддержку собственного аналога статуса 307.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[3]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 07.02.14 07:38
Оценка:
Здравствуйте, dimgel, Вы писали:

A>>Да ну брось. Пусть REST выставляет очередь на отправку емайлов. Операция PUT — помещает в очередь. Никакого мисматча

D>Как идемпотентность этого PUT обеспечивать будешь? Если он выдан дважды, может это два одинаковых письма отправить надо?

Отправка письма с защитой от потерь и дупов — это всегда проблема, если нет установленного доверия между клиентом и сервером. Как правило, сервер должен выбирать, доверять ли произвольному клиенту; реже клиент перебирает серверы в поисках доверенного. Если клиентов много и доверие к ним неизвестно, то механизмы защиты будут слишком дороги и будут допускать DDoS. Но если их немного и они адекватно аутентифицированы, то проблемы нет.

Например, на FTN транспорте проблема дупов решалась хуже, чем на UUCP, потому что на FTN в общем случае линки недоверенные (кто угодно может позвонить), а на UUCP — преднастроенные. Делалось это на UUCP так: каждое письмо отправляется в виде заявки типа rmail (rnews, etc.), а заявка состоит из D-файла и X-файла. D-файл всегда передаётся вперёд X-файла. Транспорт обеспечивает докачку (не все протоколы) и сохранение промежуточных файлов. Цена за надёжность — хранение временных файлов отправителя у приёмника между сеансами связи.

Такой же механизм переводится тривиально на REST, но — с подпоркой от клиента. А именно:

1. Делается PUT с выбранным id (кто генерирует — неважно, лишь бы случайно). Если не получилось, повторяется. Письмо при этом не отправляется, а только лежит в выходной очереди клиента на сервере. Клиент запоминает id и факт завершения этого PUT в своих локальных данных. Можно организовать докачку, если оно большое.

2. Делается сигнал посылки письма из уже сохранённого на сервере. Вот тут это вообще-то не GET и не PUT REST позволяет назначать свои методы, придумаем какой-нибудь SEND. Главное — опять же возможность повторить его несколько раз и/или потерять промежуточный ответ без побочных эффектов. Сервер должен понять, что есть заказ отправить, и сказать об этом. Отказ типа "такого id нет" аналогичен "уже отправили", но можно делать сохранение отправленных id на несколько дней, чтобы давать более конкретный ответ.

Повторюсь, что проблема не в REST, проблема в исходной задаче. Она в любом случае решается комбинацией контролей элементарной передачи, сквозной доставки, переповторов и таймаутов.
The God is real, unless declared integer.
Re[2]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: dimgel Россия https://github.com/dimgel
Дата: 07.02.14 08:03
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Без этой литературы вы, к сожалению, ничего не поймёте. Чтобы эта фраза обрела смысл, нужно налить много воды: несколько раз объяснить простые, вроде бы, вещи; привести несколько десятков примеров.


Да-да, про классификации животных по ДНК и внешнему виду. Не делайте мне смешно, всякому беспеределу должен быть предел. Я было подумал, что эта книга наверное для выпускников американских школ писалась, но они её тоже не осилят — заснут.

S>Вот видите — вы уже начали неправильно понимать. Нет такого следствия.


Значит, либо исходное утверждение не верно, либо же, как я и написал, это paradigm mismatch, в данном случае — натягивание термина "ресурс" на то, что ресурсом не является: на глаголы.

S>Выразительность и в REST и в RPC совершенно одинакова.


Ага, даже идемпотентность приходится и там, и там руками обеспечивать. :-P

S>Просто в REST больше внимания уделяется опциональным и непопулярным в RPC вещам, что обычно приводит к более высокому качеству протоколов, спроектированных через REST.

S>Всё наоборот: границы применимости RPC — это бесконечно широкие и бесконечно надёжные каналы связи между клиентом и сервером. Потому что RPC не предлагает никаких возможностей для оптимизации запросов и восстановления после сбоев.

Вот это собственно и есть единственное преимущество REST: что кое-какую работёнку за тебя уже сделали, и качество этой работёнки себя уже зарекомендовало, так что не надо изобретать велосипедное решение по обеспечению надёжности и масштабируемости.
Re[4]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sinclair Россия https://github.com/evilguest/
Дата: 07.02.14 08:04
Оценка:
Здравствуйте, dimgel, Вы писали:
D>Любопытно и доля истины ощущается. Но ограниченность множества глаголов — объективный факт. (Я ХЗ как ты относишься к типу ресурса "контроллер", мне же он кажется натягиванием презерватива на глобус — отход от концептуально правильного REST-а, пригодного в чистом виде — повторюсь — только для ресурсопомоек, в угоду суровой правде жизни.)
Спор беспредметен. Во всех предыдущих инкарнациях, REST выигрывал у RPC на его же поле. Я по-прежнему открыт к дискуссии в формате "вот схема RPC API, и по-моему это плохо воспроизводится в REST". В ответ на что я предъявляю схему REST-сервиса, который делает то же самое, плюс решает пару проблем, о которых автор RPC по наивности не подумал. Либо я соглашаюсь, что да, таки в данном случае RPC лучше, и мы наконец-то имеем хоть один пример, где RPC выигрывает.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[5]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: dimgel Россия https://github.com/dimgel
Дата: 07.02.14 08:12
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Спор беспредметен. [...] Я по-прежнему открыт к дискуссии в формате


Скажи лучше, как тебе такая идейка для отладки RESTful-сервиса: отдавать XML с <?xls-stylesheet?>, чтобы можно было прям настоящее живое API из-под браузера глазками-ручками тестировать. (Вообще, я сильно больше JSON люблю, но тут мне кажется может получиться забавно.)
Re[4]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 07.02.14 08:18
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, vsb, Вы писали:

vsb>>А можно на примере этой отправки емайлов объяснить — какое преимущество мы получаем от отправки емайла в стиле REST?
S>Очень простое — предсказуемость работы в случае сбоев. Если RPC вызов "SendMail" упал по таймауту или вернул 5хх, то нет никакого способа узнать, было ли письмо таки отправлено. Retry, возможно, приведёт к дублированию (и я раз в иногда получаю пару десятков писем от залипшего клиента), а игнор, возможно, приведёт к потере. REST позволяет мне Retry-ить в случае сомнений до получения либо 2хх либо 4хх.
Почему? Если ты ответа не получил, то так, же как и с REST отправляешь с письмом ГУИД. У меня так на SOAP прекрасно работает.
и солнце б утром не вставало, когда бы не было меня
Re[3]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Cyberax Марс  
Дата: 07.02.14 08:22
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Чтобы понять, зачем он нужен, нужно получить негативный опыт на предшествующих технологиях. Когда вы упрётесь в то, что банальный conditional get требует редизайна RPC Endpoint, что означает "давайте лучше не будем, пока перформанс не вызовет эскалацию на уровне нашего директора", вы начнёте понимать, в чём преимущество подхода с safe methods. Когда вы столкнётесь с тем, что прикручивание идемпотентности тоже требует редизайна RPC Endpoint, причём обратно-несовместимым образом

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

Т.е. делаем запрос с уникальным ID и сохраняем ответ. При повторном запросе просто отдаём клиенту сохранённый уже ответ. Работает в большинстве случаев без какой-либо переделки протокола.
Sapienti sat!
Re[3]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: avpavlov  
Дата: 07.02.14 08:46
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>Здравствуйте, avpavlov, Вы писали:



D>>>3. То есть, если нам надо отправить email, мы либо пуляем RPC поверх HTTP (раз mismatch), либо прикидываемся, что "отправка email" — это типа разновидность записи данных такая (два mismatch). Куда не плюнь — всюду mismatch.


A>>Да ну брось. Пусть REST выставляет очередь на отправку емайлов. Операция PUT — помещает в очередь. Никакого мисматча


vsb>А можно на примере этой отправки емайлов объяснить — какое преимущество мы получаем от отправки емайла в стиле REST?


Отсутствие бессоницы из-за paradigm mismatch. Если бессоницы нет и не было, то можно не париться и использовать любой подход
Re[3]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: avpavlov  
Дата: 07.02.14 08:48
Оценка:
Здравствуйте, dimgel, Вы писали:

D>Здравствуйте, avpavlov, Вы писали:


A>>Да ну брось. Пусть REST выставляет очередь на отправку емайлов. Операция PUT — помещает в очередь. Никакого мисматча


D>Как идемпотентность этого PUT обеспечивать будешь? Если он выдан дважды, может это два одинаковых письма отправить надо?


Это пусть клиент парится. Если я ему вернул ОК, а он повторно отправляет — значит так и надо. Если я ему вернул ошибку, то пусть анализирует какую именно и отправляет повторно, или внимательно набирает УРЛ или ещё чего.
Re[4]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 07.02.14 09:30
Оценка:
Здравствуйте, avpavlov, Вы писали:

A>>>Да ну брось. Пусть REST выставляет очередь на отправку емайлов. Операция PUT — помещает в очередь. Никакого мисматча


D>>Как идемпотентность этого PUT обеспечивать будешь? Если он выдан дважды, может это два одинаковых письма отправить надо?


A>Это пусть клиент парится. Если я ему вернул ОК, а он повторно отправляет — значит так и надо. Если я ему вернул ошибку, то пусть анализирует какую именно и отправляет повторно, или внимательно набирает УРЛ или ещё чего.


Вы отвечаете, даже не попытавшись понять суть проблемы. Пусть передача тела по PUT завершилась, а перед получением OK от сервера порвалась связь. Как клиент поймёт, передавать заново или нет?
The God is real, unless declared integer.
Re[4]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sinclair Россия https://github.com/evilguest/
Дата: 07.02.14 09:54
Оценка:
Здравствуйте, Cyberax, Вы писали:
C>Необязательно. Мы добавляли идемпотентность просто на уровень RPC-протокола. Не так уж и сложно, если можно хранить ответы.

C>Т.е. делаем запрос с уникальным ID и сохраняем ответ. При повторном запросе просто отдаём клиенту сохранённый уже ответ. Работает в большинстве случаев без какой-либо переделки протокола.

Это если вас внезапно осенило в тот момент, когда вы проектировали первую версию протокола. А если не осенило — упс, тупик. Вы не добавите conditional get в версии 2.0.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[5]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sinclair Россия https://github.com/evilguest/
Дата: 07.02.14 09:55
Оценка:
Здравствуйте, Serginio1, Вы писали:
S> Почему? Если ты ответа не получил, то так, же как и с REST отправляешь с письмом ГУИД. У меня так на SOAP прекрасно работает.
Это по факту означает, что вы изобрели свой собственный REST, только без его преимуществ — в частности, в REST идемпотентность PUT известна ещё до начала разработки протокола, а у вас нужно руками документировать идемпотентность вашего метода.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[5]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: avpavlov  
Дата: 07.02.14 10:06
Оценка:
N>Вы отвечаете, даже не попытавшись понять суть проблемы. Пусть передача тела по PUT завершилась, а перед получением OK от сервера порвалась связь. Как клиент поймёт, передавать заново или нет?
Почему она только для РЕСТ "нерешаема"?
Re[6]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 07.02.14 10:09
Оценка:
Здравствуйте, avpavlov, Вы писали:

N>>Вы отвечаете, даже не попытавшись понять суть проблемы. Пусть передача тела по PUT завершилась, а перед получением OK от сервера порвалась связь. Как клиент поймёт, передавать заново или нет?

A>Почему она только для РЕСТ "нерешаема"?

Она решаема. С разной степенью надёжности в зависимости от применённых средств. Но Ваш метод точно её не решит.
The God is real, unless declared integer.
Re[6]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 07.02.14 10:38
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, Serginio1, Вы писали:

S>> Почему? Если ты ответа не получил, то так, же как и с REST отправляешь с письмом ГУИД. У меня так на SOAP прекрасно работает.
S>Это по факту означает, что вы изобрели свой собственный REST, только без его преимуществ — в частности, в REST идемпотентность PUT известна ещё до начала разработки протокола, а у вас нужно руками документировать идемпотентность вашего метода.
Непроблема.В SOAP есть WS-ReliableMessaging, только в 1С нет поддержки этого протокола Зато у RESTа куча недостатков перед SOAP. Кстати ту в 1С http://v8.1c.ru/o7/201312rest/index.htm смотрят в сторону ODATA


В качестве протокола доступа платформа использует протокол OData версии 3.0. Это открытый веб-протокол для запроса и обновления данных. Он позволяет оперировать данными, используя в качестве запросов HTTP-команды. Получать ответы можно в различных форматах, но пока мы поддерживаем только работу с данными в формате Atom/XML.

В платформе мы реализовали только серверную часть REST сервисов. То есть прикладное решение может автоматически поставлять свою функциональность через REST сервисы. Для взаимодействия со сторонними REST сервисами из 1С:Предприятия (для организации клиентской части) можно использовать имеющиеся в платформе средства работы с HTTP: объекты HTTPСоединение, HTTPЗапрос и HTTPОтвет.

и солнце б утром не вставало, когда бы не было меня
Re: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: -n1l-  
Дата: 07.02.14 10:47
Оценка:
Здравствуйте, dimgel, Вы писали:
D>4. Вывод: вот и границы применимости этого вашего REST-а нарисовались: помойки данных, где любые операции, отличные от чтения/записи даных, идут как неявные побочные эффекты.
Границы видны из аббревиатуры.
Если мы имеем дело с чем-то отличным от просмотра и/или изменения состояния, то REST нам и не нужен.
Re[7]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sinclair Россия https://github.com/evilguest/
Дата: 07.02.14 10:52
Оценка:
Здравствуйте, Serginio1, Вы писали:
S> Непроблема.В SOAP есть WS-ReliableMessaging, только в 1С нет поддержки этого протокола
Ага. Это называется "сначала мы создадим себе проблему, а потом будем прикручивать к ней неприлично дорогое решение".
S> Зато у RESTа куча недостатков перед SOAP.
Ага, вот только назвать их все почему-то затрудняются.
S> Кстати ту в 1С http://v8.1c.ru/o7/201312rest/index.htm смотрят в сторону ODATA
Ну так это и есть REST.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[8]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: dimgel Россия https://github.com/dimgel
Дата: 07.02.14 11:03
Оценка:
Здравствуйте, Sharov, Вы писали:

S>Ребят, обожите. Если я правильно понял ваши идеи, то сейчас этих тестировщиков REST API

S>навалом. Есть плагины для фф и для хрома. Fiddler опять же...
S>В чем прикол?

Во-первых, в том, что я про сам факт существования этих тестировщиков раньше не слышал.

А во-вторых, в порекомендованной A13X-ом книге (в начале, до подробностей в главе про тело ответа не добрался ещё) что-то говорилось про передачу ссылок на связанные документы в составе ответа. Т.е. с помощью ссылок (игнорируемых программным клиентом) и XSLT можно очень удобную фигню замутить, с полноценной навигацией.
Re[8]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 07.02.14 11:04
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, Serginio1, Вы писали:

S>> Непроблема.В SOAP есть WS-ReliableMessaging, только в 1С нет поддержки этого протокола
S>Ага. Это называется "сначала мы создадим себе проблему, а потом будем прикручивать к ней неприлично дорогое решение".
S>> Зато у RESTа куча недостатков перед SOAP.
Прикручивать приходится потому, что 1С не поддерживает все возможности. Да понятие неприлично дорогое для меня непонятно, это пшик (2-3 строчки)по сравнению с реально написанным кодом)
Почему Метаданные и создание модели по WSDL. В RESTE пока я так понял в зачаточном положении.
S>Ага, вот только назвать их все почему-то затрудняются.
S>> Кстати ту в 1С http://v8.1c.ru/o7/201312rest/index.htm смотрят в сторону ODATA
S>Ну так это и есть REST.

Но вот в большинстве то используют SOAP потому, что его легко использовать.
и солнце б утром не вставало, когда бы не было меня
Re[8]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 07.02.14 11:30
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, Serginio1, Вы писали:

S>> Непроблема.В SOAP есть WS-ReliableMessaging, только в 1С нет поддержки этого протокола
S>Ага. Это называется "сначала мы создадим себе проблему, а потом будем прикручивать к ней неприлично дорогое решение".
Кстати а как из коробки повторная отправка письма решается на REST

Кстати это аналог реализации WS-ReliableMessaging из-за того, что 1С во многом ущербна
и солнце б утром не вставало, когда бы не было меня
Re[9]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sinclair Россия https://github.com/evilguest/
Дата: 07.02.14 13:36
Оценка:
Здравствуйте, Serginio1, Вы писали:
S> Кстати а как из коробки повторная отправка письма решается на REST
Почитайте вокруг — я в этом топике уже три раза разжевал пошаговый алгоритм "решения повторной отправки письма в REST"
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sinclair Россия https://github.com/evilguest/
Дата: 07.02.14 13:43
Оценка:
Здравствуйте, -n1l-, Вы писали:
N>Если мы имеем дело с чем-то отличным от просмотра и/или изменения состояния, то REST нам и не нужен.
Совершенно верно. Вот только распределённые приложения без состояния малоинтересны. Как только появляются разделяемые данные — сразу появляется место для REST.
Придумать пример приложения, которое бы не нуждалось в передаче состояния, довольно сложно. Наверное, что-то вроде VoIP будет таким примером. Практически всё остальное — это распределённое состояние в том или ином виде.

Вы попробуйте придумать убедительный пример распределённого приложения, которое "отлично от просмотра и изменения состояния", а мы посмотрим, ляжет оно в REST или нет.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[10]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 07.02.14 13:44
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, Serginio1, Вы писали:


S>>Прикручивать приходится потому, что 1С не поддерживает все возможности. Да понятие неприлично дорогое для меня непонятно, это пшик (2-3 строчки)по сравнению с реально написанным кодом)

S>Этот пшик требует канала обратного вызова, что вообще говоря нонсенс в современном мире. То, что за вас кто-то написал тонну говнокода, который занимается нагреванием атмосферы, не отменяет технического убожества этого решения.
S>Надо смотреть в корень: единственным способом борьбы с отказами в распределённой системе является идемпотентность. REST, как подход, ставит эту идемпотентность на важное место и уделяет ей должное внимание. А SOAP начинает с отказа от идемпотентности, а потом придумывает себе адски сложные и дорогие в эксплуатации надстройки для возврата идемпотентности туда, где её не было.
Кстати а как Идемпотентность решена в RESTE?

S>> Но вот в большинстве то используют SOAP потому, что его легко использовать.

S>Его легко использовать не потому, что он хороший, а потому, что к моменту выхода REST на сцену в SOAP уже были вбуханы миллиарды. Это как ездить в "киоск во дворе" на джипе: адски неэффективно "под капотом", но если у вас уже есть корпоративный джип, то вы таки будете им пользоваться даже для этого. А вот предлагать купить джип ради поездок за бутылкой пива на расстояние в 80 метров и обратно — это, простите, долбоклюйство.
Да мне глубоко по барабану сколько и что весит пока это работает быстро и быстро разрабатывается. А вот когда будут тормоза я наплюю на сложность и я начну оптимизировать усложняя клиентскую часть.
Хотя сейчас занялся сайтописанием на ASP.Net mvc сервер сделать очень просто и на его основании сварганить клиента. Но вот с 1С это проблема, хотя там просто использовать оболочку из IReflect к сборкам.
и солнце б утром не вставало, когда бы не было меня
Re[10]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 07.02.14 14:01
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, Serginio1, Вы писали:

S>> Кстати а как из коробки повторная отправка письма решается на REST
S>Почитайте вокруг — я в этом топике уже три раза разжевал пошаговый алгоритм "решения повторной отправки письма в REST"
Поиск не работает. Мне интересно как на физическом уровне. Понятно, что должно где то храниться ID запроса. И насколько это накладно для всех видов запросов.
и солнце б утром не вставало, когда бы не было меня
Re[5]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Cyberax Марс  
Дата: 07.02.14 14:57
Оценка:
Здравствуйте, Sinclair, Вы писали:

C>>Т.е. делаем запрос с уникальным ID и сохраняем ответ. При повторном запросе просто отдаём клиенту сохранённый уже ответ. Работает в большинстве случаев без какой-либо переделки протокола.

S>Это если вас внезапно осенило в тот момент, когда вы проектировали первую версию протокола. А если не осенило — упс, тупик. Вы не добавите conditional get в версии 2.0.
У меня был опыт добавления этой функциональности в готовый проект. Ничего, вполне справились — все изменения можно ограничить протокольным уровнем, не влияя на остальной код.

Конечно, у этого метода есть ограничения для highload и прочего, но далеко не всегда они критичны.
Sapienti sat!
Re[3]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: andyag  
Дата: 07.02.14 15:55
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, andyag, Вы писали:


A>>// Я вообще не фанат REST — просто смотрю на это всё со стороны и пытаюсь понять зачем этот REST нужен. Пока не понял. Субъективно — не нужен.

S>Чтобы понять, зачем он нужен, нужно получить негативный опыт на предшествующих технологиях. Когда вы упрётесь в то, что банальный conditional get требует редизайна RPC Endpoint, что означает "давайте лучше не будем, пока перформанс не вызовет эскалацию на уровне нашего директора", вы начнёте понимать, в чём преимущество подхода с safe methods. Когда вы столкнётесь с тем, что прикручивание идемпотентности тоже требует редизайна RPC Endpoint, причём обратно-несовместимым образом, что означает "давайте лучше не будем, пока количество сбоев не вызовет эскалацию на уровне нашего директора", вы поймёте, что REST всего лишь заставляет вас думать о реальности.
S>Да, приходится втискивать предметную область в непривычные рамки. Но на самом деле никакого mismatch нету — он появляется искусственно, когда сначала предметная область втискивается в рамки RPC. Просто эти рамки привычнее, и для втискивания в них не нужно делать почти никакого усилия. А вот потом, при "перевтискивании" приходится напрягать мозг, и возникает иллюзия какой-то неправильности.

S>Аналогом может являться представление звукового сигнала. Если привыкнуть представлять его в виде "отсчётов" — измерений амплитуды во времени, то переход к частотному представлению кажется совершенно противоестественным. Типа "ну и как я буду теперь отрезать первые 5 секунд от этой записи?" Зато в частотном представлении становятся удобными другие операции — например, фильтры низких/высоких частот.


Вы очень субъективно это воспринимаете. Есть дофига задач, где ценности, которые вы описываете — это не ценности, а рюшечки (как со стороны программирования, так и со стороны ценности для продукта). Если в вашей практике таких задач либо не было, либо было мало, безусловно вы станете ссылаться на 95% своего опыта (если вы, например, "старший архитектор интеграционных решений"). Но это только ваш опыт. Например, в том мире, где я живу "отправить письмо 2 раза" — это фигня — ну два ды, два. Ни холодно, ни жарко. Удалить одну сущность 2 раза, где второй раз упадёт с ошибкой — это тоже фигня: нажал "Ок", пошёл дальше. Затачивать API под вполне конкретный юзкейз, под одного-двух клиентов, вроде сайта и айфона, тоже нормально. REST это не "правильнее" и REST это не "лучше", REST это "типовое решение", которое можно применить, если у проекта есть задачи, которые можно решить с помощью этого типового решения. Если таких задач нет, REST будет просто "вытягиванием денег и времени".
Re[5]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: dimgel Россия https://github.com/dimgel
Дата: 08.02.14 03:08
Оценка:
Здравствуйте, Sinclair,

А можно ещё вопрос?

PUT should be used to add a new resource to a store or update a resource. [...] POST should be used to create a new resource within a collection and execute controllers.


А почему добавление в store — PUT, а в collection — POST? Причём изменение ресурса, в т.ч. элемента коллекции — тоже PUT, то нафига тут POST вообще? Если дело в том, что PUT идемпотентный, то может у меня store допускает задвоения экземпляров?
Re[6]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: fddima  
Дата: 08.02.14 03:49
Оценка:
Здравствуйте, dimgel, Вы писали:

D>

PUT should be used to add a new resource to a store or update a resource. [...] POST should be used to create a new resource within a collection and execute controllers.

D>А почему добавление в store — PUT, а в collection — POST? Причём изменение ресурса, в т.ч. элемента коллекции — тоже PUT, то нафига тут POST вообще? Если дело в том, что PUT идемпотентный, то может у меня store допускает задвоения экземпляров?
Заранее говорю — это всё очень ИМХО (хотя к ИМХО никакие "очень" и так не применимы).
Всё очень просто. Нужно аппелировать к здравой логике, а не к REST или RPC. Кто-бы что ни говорил, REST — и есть настоящий RPC, только с какими-то предзаданными правилами, которые никто не обязан соблюдать.
Защитникам REST (Sinclair) — заранее говорю, — мне идея нравится. Но, всё таки, для меня — это в большей степени чушь. Чушь не сколько в подходе, а сколько в виденных реализациях. 3-rd party товарищи умудряющтся отвечать NaN в JSON, что никак недопустимо. И это делают какие-то стандартные библиотеки, скорее всего около "стандартных" навроде JSON.NET. При чём тут REST — да ни при чём, в том то и дело.
Поэтому пока вы все тратите время на REST vs RPC — лучше потратьте его, на то, что бы соответствовать самими же любимым стандартам (если таковые имеются). Все valuable-peoples судя из всего топика отлично понимают как сделать надежную коммуникацию что в "REST" что в "RPC".
Но самое главное — *любой* запрос к HTTP серверу — уже по сути RPC. Более того, когда веб-сервер пишет в лог, что к нему обратились по GET — это уже "RPC", а не REST, ибо состояние очень даже меняется.
Логи не нужны для бизнеса? Это враки. Нужны (хотя видимо не всего подряд).
Поэтому в целом — спорите ни о чём.
Мне нравится REST, в том смысле, что и правда декларируется идемпотентность, или хотя бы о ней заставляет задуматься... ух сколько даже ново-разрабатываемых протоколов о таком не знают — сложно даже представить (на своём опыте видел). И вроде даже не "васи" делают.
Поэтому — суть не в REST-то. С хорошо спроектированным и документированным сервисом, REST-или-не-REST — всегда приятно работать. И обратное — если дока криволапая, и сервис такой же. Такова моя практика.
Re[7]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: dimgel Россия https://github.com/dimgel
Дата: 08.02.14 04:01
Оценка:
Здравствуйте, fddima, Вы писали:

D>>А почему добавление в store — PUT, а в collection — POST? Причём изменение ресурса, в т.ч. элемента коллекции — тоже PUT, то нафига тут POST вообще? Если дело в том, что PUT идемпотентный, то может у меня store допускает задвоения экземпляров?


F>Заранее говорю — это всё очень ИМХО (хотя к ИМХО никакие "очень" и так не применимы).


Да в общем-то я спрашивал про совершенно конкретный сугубо утилитарный момент, чтобы не сделать по-своему и не вляпаться в непонимание клиентских реализаций. Когда задаёшь вопрос "как на жаве сложить 2+2", ожидаешь ответ-таки по существу, а не в духе "жава — всего лишь один из языков, и не обязательно самый лучший, и сложение во всех языках есть". Про философию эту все и так более-менее в курсе.
Re[10]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Cyberax Марс  
Дата: 08.02.14 04:03
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>То есть вместо возврата непрозрачных идентификаторов, которые нужно как-то угадать куда вставлять, в ресте рекомендуется возвращать прямо честные URL, по которым можно сделать GET (ну, или другие глаголы).

Ну вот нынче писали REST API. Ну и @!@$*&@# этот REST. Скажем, несколько объектов в одной транзакции поменять нормально нельзя.

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

Любой надёжный метод делается через полную задницу, в два шага (получить тикет, потом сделать запрос).
Sapienti sat!
Re[11]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: dimgel Россия https://github.com/dimgel
Дата: 08.02.14 04:10
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Скажем, несколько объектов в одной транзакции поменять нормально нельзя.


Можно, сделав "POST /controller". Т.е. выйдя за рамки чистого REST.

C>В теории есть метод PATCH, который делает частичные обновления, но знаю про него только я.


Насколько я понимаю, никто не запрещает с клиента передавать в PUT не полный набор свойств. (Или ошибаюсь?)

C>Любой надёжный метод делается через полную задницу, в два шага (получить тикет, потом сделать запрос).


Про генерацию типа-GUID на клиенте я тут уже нагуглил: http://stackoverflow.com/a/2117523

А вообще, за всё надо платить, вот. Не знаю кто как, а лично я сербряной пули не ищу.
Re[12]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Cyberax Марс  
Дата: 08.02.14 04:17
Оценка:
Здравствуйте, dimgel, Вы писали:

C>>Скажем, несколько объектов в одной транзакции поменять нормально нельзя.

D>Можно, сделав "POST /controller". Т.е. выйдя за рамки чистого REST.
Ну так у нас и RPC тоже поверх HTTP работает.

C>>В теории есть метод PATCH, который делает частичные обновления, но знаю про него только я.

D>Насколько я понимаю, никто не запрещает с клиента передавать в PUT не полный набор свойств. (Или ошибаюсь?)
Можно. Но в стандарте ничего не сказано про опциональные свойства, например.

C>>Любой надёжный метод делается через полную задницу, в два шага (получить тикет, потом сделать запрос).

D>Про генерацию типа-GUID на клиенте я тут уже нагуглил: http://stackoverflow.com/a/2117523
Небезопасно, если на сервере не проверять уникальность GUID-ов + предсказуемость.
Sapienti sat!
Re[9]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: dimgel Россия https://github.com/dimgel
Дата: 08.02.14 04:36
Оценка:
Здравствуйте, fddima, Вы писали:

F> Я в большей степени по этому и удивлён каким-то этим спорам, когда сравнивается одна фундаментальная вещь (RPC) с модно-конкретной (REST).


Можно считать, что REST — это паттерн. Внутри приложения тоже можно просто как попало non-remote методы вызывать, безо всяких паттернов.

F> PS: POST — есть Create. PUT — есть Update. Реализация идемпотентности к POST (а она нужна) — зависит полностью от тебя, что бы там умы не говорили.


В моей исходной цитате PUT предлагалось в качестве add to store. Хочешь сказать, что это не create?
Re[11]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sinclair Россия https://github.com/evilguest/
Дата: 08.02.14 06:46
Оценка:
Здравствуйте, Cyberax, Вы писали:
C>Ну вот нынче писали REST API. Ну и @!@$*&@# этот REST. Скажем, несколько объектов в одной транзакции поменять нормально нельзя.
Это да, транзакции требуют специального проектирования — вместо 2х PUT на объект account делается 1 PUT на объект transfer.
C>В теории есть метод PATCH, который делает частичные обновления, но знаю про него только я.
А он вам часто нужен? Почему нельзя заэкспозить нужные части как отдельные адресуемые объекты?
C>Любой надёжный метод делается через полную задницу, в два шага (получить тикет, потом сделать запрос).
Почему ваш любой надёжный метод не свёлся к PUT? Зачем вам получать тикет — на клиенте нет генератора GUID?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[11]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 08.02.14 07:25
Оценка:
Здравствуйте, Cyberax, Вы писали:

S>>То есть вместо возврата непрозрачных идентификаторов, которые нужно как-то угадать куда вставлять, в ресте рекомендуется возвращать прямо честные URL, по которым можно сделать GET (ну, или другие глаголы).

C>Ну вот нынче писали REST API. Ну и @!@$*&@# этот REST. Скажем, несколько объектов в одной транзакции поменять нормально нельзя.
C>В теории есть метод PATCH, который делает частичные обновления, но знаю про него только я.
C>Любой надёжный метод делается через полную задницу, в два шага (получить тикет, потом сделать запрос).

Ну так он и по любому RPC делается точно так же. Двухфазную фиксацию в СУБД придумали не зря. Построение транзакций со стороны клиента так, чтобы проверять в случае обрыва, прошла она или нет — тоже.

Нельзя обмануть фундаментальные физические законы, а несинхронность состояния клиента и сервера в процессе их обмена можно приравнять к таким законам, или напрямую вычислить из них. Можно только сделать средства контроля этого настолько занудным, насколько хватит.
The God is real, unless declared integer.
Re[11]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sinclair Россия https://github.com/evilguest/
Дата: 09.02.14 16:35
Оценка:
Здравствуйте, fddima, Вы писали:
F> Думаю, что create — всё таки должен быть POST.
Только если нет другого выхода, или когда не страшно наплодить дубликатов. Например, через POST удобнее всего получать тикеты для последующих идемпотентных операций — неиспользованные тикеты ничего не стоят.
F>Хотя PUT, в случае когда id (url) создаваемого ресурса заранее известен — наверное тоже может быть применён.
Именно.
F>Но я бы так не делал.
А зря. Зачем мучиться, приделывая идемпотентность к POST, когда есть готовый понятный PUT?
F>Да и мне не встречались чужие сервисы которые бы так делали.
Полно таких сервисов. Вот первое, что попалось: http://msdn.microsoft.com/en-us/library/windowsazure/dd179451.aspx
F> CRUD = PGPD (POST — GET — PUT — DELETE)
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[12]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: dimgel Россия https://github.com/dimgel
Дата: 09.02.14 16:39
Оценка:
Здравствуйте, Sinclair, Вы писали:

F>>Хотя PUT, в случае когда id (url) создаваемого ресурса заранее известен — наверное тоже может быть применён.

S>Именно.

Эм... А часто ли он известен? Тут как бы по ощущениям подразумевается, что в базе PK — GUID-ы, генерируемые как раз как номера тикетов, так?
Re[13]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: dimgel Россия https://github.com/dimgel
Дата: 09.02.14 16:42
Оценка:
D>Здравствуйте, Sinclair, Вы писали:

F>>>Хотя PUT, в случае когда id (url) создаваемого ресурса заранее известен — наверное тоже может быть применён.

S>>Именно.

D>Эм... А часто ли он известен? Тут как бы по ощущениям подразумевается, что в базе PK — GUID-ы, генерируемые как раз как номера тикетов, так?


Хотя GUID-ы клиент и сам генерить может. А если подсунет левый и что-нибудь из доступных ему на запись данных сломает, тут уж звиняйте, ССЗБ.
Re[12]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Cyberax Марс  
Дата: 09.02.14 20:43
Оценка:
Здравствуйте, Sinclair, Вы писали:

C>>Ну вот нынче писали REST API. Ну и @!@$*&@# этот REST. Скажем, несколько объектов в одной транзакции поменять нормально нельзя.

S>Это да, транзакции требуют специального проектирования — вместо 2х PUT на объект account делается 1 PUT на объект transfer.
Ага, особенно если нужно штучек так 100 объектов поменять. Кстати, для множественных операций в REST тоже ничего особого нет.

C>>В теории есть метод PATCH, который делает частичные обновления, но знаю про него только я.

S>А он вам часто нужен? Почему нельзя заэкспозить нужные части как отдельные адресуемые объекты?
Ну вот оказался нужен. Но почти никакие клиентские библиотеки его не поддерживают.

C>>Любой надёжный метод делается через полную задницу, в два шага (получить тикет, потом сделать запрос).

S>Почему ваш любой надёжный метод не свёлся к PUT? Зачем вам получать тикет — на клиенте нет генератора GUID?
Нельзя доверять тому, что у клиента UUID'ы будут надёжными. Так что надо или делать stateful-сессии и беспокоиться об уникальности UUID'ов только внутри них, или серверные тикеты. В принципе, получается то же самое — один лишний database write на запрос.

В общем, надёжность должна быть на уровне протокола.
Sapienti sat!
Re[13]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sinclair Россия https://github.com/evilguest/
Дата: 10.02.14 05:21
Оценка:
Здравствуйте, Cyberax, Вы писали:
C>Ага, особенно если нужно штучек так 100 объектов поменять. Кстати, для множественных операций в REST тоже ничего особого нет.
Да хоть 1000 — принцип тот же.

C>Ну вот оказался нужен.

А подробнее можно?
C>Нельзя доверять тому, что у клиента UUID'ы будут надёжными.
Почему?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[14]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Cyberax Марс  
Дата: 10.02.14 05:32
Оценка:
Здравствуйте, Sinclair, Вы писали:

C>>Ага, особенно если нужно штучек так 100 объектов поменять. Кстати, для множественных операций в REST тоже ничего особого нет.

S>Да хоть 1000 — принцип тот же.
Ну да, то есть никакого.

C>>Ну вот оказался нужен.

S>А подробнее можно?
Оказалось нужно различить PUT с дефолтными значениями и PATCH изменившихся.

C>>Нельзя доверять тому, что у клиента UUID'ы будут надёжными.

S>Почему?
Делаем такую последовательность:
user_id = create_new_user()
assign_roles_to_user(user_id, admin_role_id)


Если враг может сделать так, что для create_new_user() будет конфликт UUID'ов, то есть шанс подменить user_id на контролируемый врагом.
Sapienti sat!
Re[15]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sinclair Россия https://github.com/evilguest/
Дата: 10.02.14 06:15
Оценка:
Здравствуйте, Cyberax, Вы писали:
S>>Да хоть 1000 — принцип тот же.
C>Ну да, то есть никакого.
Что значит "никакого"? Принцип — делаем PUT в объект "Transaction".

S>>А подробнее можно?

C>Оказалось нужно различить PUT с дефолтными значениями и PATCH изменившихся.
Не до конца понимаю. Это же ваш протокол, что мешало внести в него понятия (reset-to-default), (clear), (leave-as-is) в дополнение к установке конкретного значения?

S>>Почему?

C>Делаем такую последовательность:
C>
C>user_id = create_new_user()
C>assign_roles_to_user(user_id, admin_role_id)
C>


C>Если враг может сделать так, что для create_new_user() будет конфликт UUID'ов, то есть шанс подменить user_id на контролируемый врагом.

Продолжаю не понимать. То есть вы хотите сказать, что клиент 1 (привилегированный) делает типа assign_roles(admin_role), а клиент 2 (непривилегированный) делает reset_password(), и всё это на один и тот же user_id?
Пока что я не могу себе представить, каким образом клиент 2 может предсказать GUID, сгенерированный на клиенте 1.

Меня пугает непонятное — расскажите поподробнее. (Вопрос не праздный, если сценарий, о котором вы говорите, реализуем, то существует уязвимость, актуальная для всех нынешних и будущих приложений на стандарте APS2)
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[16]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Jack128  
Дата: 10.02.14 06:31
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>>>Почему?

C>>Делаем такую последовательность:
C>>
C>>user_id = create_new_user()
C>>assign_roles_to_user(user_id, admin_role_id)
C>>


C>>Если враг может сделать так, что для create_new_user() будет конфликт UUID'ов, то есть шанс подменить user_id на контролируемый врагом.

S>Продолжаю не понимать. То есть вы хотите сказать, что клиент 1 (привилегированный) делает типа assign_roles(admin_role), а клиент 2 (непривилегированный) делает reset_password(), и всё это на один и тот же user_id?
S>Пока что я не могу себе представить, каким образом клиент 2 может предсказать GUID, сгенерированный на клиенте 1.
А зачем предсказывать?? ставишь снифер клиенту1 и видишь, что тот обращается по урлу www.example.com/api/users/F889A953B7C543AB82762A2E02E299BF вот те гуид и есть. Другое дело, что если "клиент 2 (непривилегированный)" может обресетить пароль, то это вообще какая та странная безопасность. И никакими тикитами с сервера тут не защитится.
Re[17]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: dimgel Россия https://github.com/dimgel
Дата: 10.02.14 06:35
Оценка:
Здравствуйте, Jack128, Вы писали:

J>обращается по урлу www.example.com/api/users/F889A953B7C543AB82762A2E02E299BF


А вот меня кстати ещё с книжки смущает кодировать id|login|api_key текущего юзера в URL. Если мне, к примеру, не нужно между юзерами ничего шарить, т.е. они полностью изолированы друго от друга, я хочу юзать /my/contacts вместо /users/KEY/contacts (или вместо прилагательного my принято что-то другое юзать) + HTTP authorization (пишут ещё про какой-то OAuth, но мне в него лениво и наверняка он браузерами не поддерживается).
Re[12]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 10.02.14 06:37
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, Serginio1, Вы писали:

S>> Поиск не работает.
S>Зачем поиск? В этой теме не так много постов.

S>> Мне интересно как на физическом уровне. Понятно, что должно где то храниться ID запроса. И насколько это накладно для всех видов запросов.

S>Нет никакого ID запроса. У каждого объекта есть URL. Операции с объектом делятся на safe, idempotent, и операцию POST. Поэтому ничего "отдельно" хранить не надо.
Ну вот я отправляю письмо. Должен ему присвоить какой URL в котом содержится ID этого письма, что бы при повторной посылке POST оно не отправлялось, а получался ответ который до меня не дошел. Так же и с GET если я запрашиваю справочник по ID то согласно idempotent мне по этому ID должен возвращаться всегда одни и теже данные. Идемпотентность
Согласно этому определению

Идемпотентная операция в информатике — действие, многократное повторение которого эквивалентно однократному.

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



Кстати часто возникают проблемы с кэшированием, когда данные изменились, а ответ возвращается один и тот же. Тогда я понимаю что бы избавиться от идемпотентности можно добавить GUID или метку времени в строку запроса?
и солнце б утром не вставало, когда бы не было меня
Re[17]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sinclair Россия https://github.com/evilguest/
Дата: 10.02.14 06:37
Оценка:
Здравствуйте, Jack128, Вы писали:

J>А зачем предсказывать?? ставишь снифер клиенту1 и видишь, что тот обращается по урлу www.example.com/api/users/F889A953B7C543AB82762A2E02E299BF вот те гуид и есть. Другое дело, что если "клиент 2 (непривилегированный)" может обресетить пароль, то это вообще какая та странная безопасность. И никакими тикитами с сервера тут не защитится.

Вот именно. Случай, когда клиент 2 может сбросить пароль кому угодно — это такая дыра в безопасности, что её и обсуждать не стоит.
Обсуждаемый случай — это угон GUID. Пытаться его угнать после того, как его сгенерировал клиент 1, бесполезно — разделение прав доступа не даст нам ничего сделать. Единственная возможная дыра — это предсказать GUID и "застолбить" его, пользуясь неразличимостью действий "создать" и "изменить" в REST. Поскольку клиент 1 — привилегированный, система безопасности типа даст ему назначить админские права "чужому" аккаунту.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[17]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sinclair Россия https://github.com/evilguest/
Дата: 10.02.14 06:45
Оценка:
Здравствуйте, Cyberax, Вы писали:
C>Сотню запросов с латентностью в 200-300 миллисекунд? Ну-ну.
Ничего не понимаю. Мы всё ещё про атомарное изменение пачки объектов? Я же говорю: делается 1 (один) PUT в объект transaction. Откуда взялась сотня запросов?

C>Код библиотеки на JS так не умеет.

Код какой библиотеки?

C>Нет. Враг угадывает какой UUID будет у запроса create_new_user() от привиллегированного пользователя и использует этот UUID при создании пользователя под своим контролем.

1. И каким образом враг может угадать, какой UUID будет у запроса create_new_user()?

2. Непонятно, почему вы не можете защитить протокол, разведя адреса пользователей по разным namespace. Грубо говоря, клиент 1 создаёт пользователей по адресам /client1/7a342ca2-e79f-528e-6302-8f901b0b6888, клиент2 — /client2/7a342ca2-e79f-528e-6302-8f901b0b6888. Вариант — каждый создаёт пользователей с идентификаторами типа username@domain.tld, где domain.tld принадлежат соответствующим клиентам и создать пользователя в чужом домене невозможно (так, например, работает Office 365).

C>Решения:

C>1) Сделать клиентский токен полностью алгоритмическим, включив туда ID пользователя и секретные данные. Так поступает, например, Amazon. Недостаток: сложность реализации, не всякий клиент может иметь доступ ко всем нужным HTTP-заголовкам.
C>2) Серверные тикеты с проверкой авторизации, включая возможность выдать сразу N тикетов.
Либо вы чего-то недоговариваете, либо вы не видите простых и очевидных решений простой проблемы.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[18]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sinclair Россия https://github.com/evilguest/
Дата: 10.02.14 06:49
Оценка:
Здравствуйте, dimgel, Вы писали:
D>А вот меня кстати ещё с книжки смущает кодировать id|login|api_key текущего юзера в URL. Если мне, к примеру, не нужно между юзерами ничего шарить, т.е. они полностью изолированы друго от друга, я хочу юзать /my/contacts вместо /users/KEY/contacts (или вместо прилагательного my принято что-то другое юзать) + HTTP authorization (пишут ещё про какой-то OAuth, но мне в него лениво и наверняка он браузерами не поддерживается).
Это — плохая идея. Есть такой набор стандартных "плохих идей", желание следовать которым нужно из себя выдавливать. В мире СУБД это желание иметь PK int indentity "без дырок"; в мире Web — иметь одинаковый адрес для разных данных. Это мешает всем встроенным инструментам: ответы на такие запросы нельзя кэшировать; минимальные ошибки конфигурации прокси могут привести к показу чужих данных; легко ошибиться, используя ссылку из одного контекста в другом контексте.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[17]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Jack128  
Дата: 10.02.14 06:52
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Здравствуйте, Sinclair, Вы писали:


S>>>>Да хоть 1000 — принцип тот же.

C>>>Ну да, то есть никакого.
S>>Что значит "никакого"? Принцип — делаем PUT в объект "Transaction".
C>Сотню запросов с латентностью в 200-300 миллисекунд? Ну-ну.

C>>>Оказалось нужно различить PUT с дефолтными значениями и PATCH изменившихся.

S>>Не до конца понимаю. Это же ваш протокол, что мешало внести в него понятия (reset-to-default), (clear), (leave-as-is) в дополнение к установке конкретного значения?
C>Код библиотеки на JS так не умеет.

C>>>Если враг может сделать так, что для create_new_user() будет конфликт UUID'ов, то есть шанс подменить user_id на контролируемый врагом.

S>>Продолжаю не понимать. То есть вы хотите сказать, что клиент 1 (привилегированный) делает типа assign_roles(admin_role), а клиент 2 (непривилегированный) делает reset_password(), и всё это на один и тот же user_id?
C>Нет. Враг угадывает какой UUID будет у запроса create_new_user() от привиллегированного пользователя и использует этот UUID при создании пользователя под своим контролем.

C>Затем привиллегированный пользователь делает create_new_user() с этим же UUID'ом и ему попадает уже существующий пользователь, которого создал враг, так как для сервера это кажется просто повторением запроса из-за ошибки клиента.


А почему бы привилегированному пользователю просто не поверить, что ему возвращается 201?
Re[18]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Cyberax Марс  
Дата: 10.02.14 06:58
Оценка:
Здравствуйте, Sinclair, Вы писали:

C>>Сотню запросов с латентностью в 200-300 миллисекунд? Ну-ну.

S>Ничего не понимаю. Мы всё ещё про атомарное изменение пачки объектов? Я же говорю: делается 1 (один) PUT в объект transaction. Откуда взялась сотня запросов?
Т.е. мы делаем PUT данных для всех объектов? Как?

C>>Код библиотеки на JS так не умеет.

S>Код какой библиотеки?
Что-то на основе Chaplin.

C>>Нет. Враг угадывает какой UUID будет у запроса create_new_user() от привиллегированного пользователя и использует этот UUID при создании пользователя под своим контролем.

S>1. И каким образом враг может угадать, какой UUID будет у запроса create_new_user()?
Ну вот программист-идиод на клиенте (которого мы не контролируем) использовал текущее время в качестве UUID'а. Или использовал random-UUID, но с предсказуемой последовательностью.

S>2. Непонятно, почему вы не можете защитить протокол, разведя адреса пользователей по разным namespace. Грубо говоря, клиент 1 создаёт пользователей по адресам /client1/7a342ca2-e79f-528e-6302-8f901b0b6888, клиент2 — /client2/7a342ca2-e79f-528e-6302-8f901b0b6888.

Это всё полумеры. Могут быть более сложные сценарии, например, если непривиллегированный пользователь пытается облапошить админа своего же домена. Типичный способ реализации идемпотентности с минимальными расходами — в БД записываем client UUID в поле в таблицу user, так что всё прекрасно сломается.

Или это могут быть не пользователи вообще, а другие чувствительные к безопасности объекты.
Sapienti sat!
Re[19]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: dimgel Россия https://github.com/dimgel
Дата: 10.02.14 07:11
Оценка:
Здравствуйте, netch80, Вы писали:

N>Но REST в описанном виде рассчитан в том числе и на участие промежуточных HTTP proxy с локальными кэшами


Point taken, thanks.
Re[19]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: dimgel Россия https://github.com/dimgel
Дата: 10.02.14 07:14
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Это — плохая идея. Есть такой набор стандартных "плохих идей", желание следовать которым нужно из себя выдавливать.


Выдавить-то не проблема, но для этого этот набор надо сначала знать.

S>В мире СУБД это желание иметь PK int indentity "без дырок"


Упс, первый раз слышу. Кто и зачем этого может пожелать? (Смутно помню стародавние срачи про производительность индексов, но мне это всё казалось слишком далёким от реальной жизни простых смертных.)
Re[14]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: dimgel Россия https://github.com/dimgel
Дата: 10.02.14 07:47
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Решается предельно просто: версия библиотеки вшивается в URL, тело отдаётся с хидерами Expiration:never.


Я дописываю версию (а точнее, mtime и/или filesize и/или md5 — в зависимости от языка) в Query String.
Re[19]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sinclair Россия https://github.com/evilguest/
Дата: 10.02.14 07:49
Оценка:
Здравствуйте, Cyberax, Вы писали:
C>Т.е. мы делаем PUT данных для всех объектов? Как?
Это вопрос к проектировщику протокола. Я же приводил пример с переводом со счёта на счёт: вместо 2х PUT на .../account1, .../account2 делается 1 PUT на /transactions/{id}/, а в теле указаны account1, account2, и сумма перевода.
Я не знаю специфики вашего протокола, и сценариев, в рамках которых нужно атомарно поменять 100 объектов. Знал бы — предложил бы решение.

C>>>Код библиотеки на JS так не умеет.

S>>Код какой библиотеки?
C>Что-то на основе Chaplin.
А почему не выбросить эту библиотеку и не написать свою? Кстати, если бы вы писали API на SOAP, то вам что, проще было бы? Есть какие-то JavaScript библиотеки с

C>Ну вот программист-идиод на клиенте (которого мы не контролируем) использовал текущее время в качестве UUID'а. Или использовал random-UUID, но с предсказуемой последовательностью.

Непонятно, почему вас это волнует, а то, что идиод может использовать один и тот же пароль для всех пользователей — нет.
Непонятно, почему вы думаете, что существует программист, настолько умный, что его не устроит штатная реализация UUIDCreate(), но настолько тупой, что своя реализация будет предсказуемой. Непонятно, каким образом злоумышленник суммет получить доступ к коду этого клиента, чтобы найти уязвимость.
В общем, либо вы чего-то недоговариваете, либо у вас беспочвенная паранойя. Нужно понимать, что уязвимости клиента вы в любом случае не контролируете (кроме случая, когда клиентом является ваш же веб-сайт), поэтому вам нужно сосредоточиться на том, как дать API, позволяющий безопасную реализацию клиента. Реализовать API, запрещающий реализацию небезопасного клиента всё равно невозможно.

C>Это всё полумеры. Могут быть более сложные сценарии, например, если непривиллегированный пользователь пытается облапошить админа своего же домена. Типичный способ реализации идемпотентности с минимальными расходами — в БД записываем client UUID в поле в таблицу user, так что всё прекрасно сломается.

Вы недоговариваете. Либо у вас какие-то конские требования к безопасности (но тогда вы огребаете и при RPC API в той же мере), либо у вас беспочвенные фантазии.
C>Или это могут быть не пользователи вообще, а другие чувствительные к безопасности объекты.
У всех чувствительных к безопасности объектов работают права доступа. Это и есть основной способ защиты от злоупотреблений. Сценарий конфликта идентификаторов приводит в REST к "кто последний, того и тапки", поэтому хитровывернутые пользователи, предсказывающие идентификаторы, просто теряют "свои" объекты.
Причинять ущерб себе самому — неотъемлемое право каждого идиота. Обязанность проектировщиков — дать нормальный способ избежать причинения ущерба, плюс обеспечить защиту от случайной ошибки.
В частности, сценарий с угоном пользователя не работает уже потому, что при PUT сбросится всё: и пароль, и емейл для password recovery, и набор прав. Поэтому всё, что получит злоумышленник — это authentication failed при попытке воспользоваться привилегированным аккаунтом. Если у вас не так — то это проблема реализации, а не REST.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[14]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: dimgel Россия https://github.com/dimgel
Дата: 10.02.14 07:52
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Для первичных запросов такая техника не очень подходит. Дело в том, что при длинной экспирации нужен механизм оповещения об устаревании кэша. Во вторичных запросах механизм опирается на изменение src в основной странице, поэтому он прекрасно подходит для стилей, картинок, и скриптов. А для самой страницы такого механизма нет. То есть можно сделать мат в два хода: например, при запросе http://news.com/latest возвращать 302 Found на "последнюю" новость, отдавая location типа: http://news.com/2014/02/10/1788/.

S>Увы:
S>1. Большинство браузеров поменяют URL текущей страницы на переданный, так что последовательное нажатие F5 уже никогда не обновит страницу
S>2. При обновлении новостей придётся делать два запроса — что хуже, чем один с conditional get.

Ctrl+F5 рулит, гыгы.

Ещё можно сделать всё на ажаксе, а в корень прогружать пустую bootstrap-страницу.

А вообщеЮ в HTTP кеширование несколько противоестественное, потому что решение принимает клиент, который может вообще игнорировать заголовки сервера, причём в обе стороны: Ctrl+F5 чтобы всегда грузить, или вон system.console со своей Оперой (на редкость беспредельничающий браузер, и был таковым с самого начала: "ускорение загрузки" за счёт наплевательского отношения к протоколу).
Re[20]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Cyberax Марс  
Дата: 10.02.14 08:05
Оценка:
Здравствуйте, Sinclair, Вы писали:

C>>Т.е. мы делаем PUT данных для всех объектов? Как?

S>Это вопрос к проектировщику протокола. Я же приводил пример с переводом со счёта на счёт: вместо 2х PUT на .../account1, .../account2 делается 1 PUT на /transactions/{id}/, а в теле указаны account1, account2, и сумма перевода.
Так и где здесь REST? Вижу обычный RPC.

C>>Что-то на основе Chaplin.

S>А почему не выбросить эту библиотеку и не написать свою? Кстати, если бы вы писали API на SOAP, то вам что, проще было бы? Есть какие-то JavaScript библиотеки с
SOAP был бы проще, уже почти жалеем, что не выбрали его. Заодно меньше проблем с валидацией схемы данных с ним.

C>>Ну вот программист-идиод на клиенте (которого мы не контролируем) использовал текущее время в качестве UUID'а. Или использовал random-UUID, но с предсказуемой последовательностью.

S>Непонятно, почему вас это волнует, а то, что идиод может использовать один и тот же пароль для всех пользователей — нет.
Авторизацией занимаемся мы сами, идиод будет получать только специальный токен.

S>Непонятно, почему вы думаете, что существует программист, настолько умный, что его не устроит штатная реализация UUIDCreate(), но настолько тупой, что своя реализация будет предсказуемой. Непонятно, каким образом злоумышленник суммет получить доступ к коду этого клиента, чтобы найти уязвимость.

Клиент — на JS.

Не веришь, что бывают уязвимые GUID'ы? Вот пожалуйста, почитай тред на SO: http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript — ВСЕ примеры оттуда уязвимы чуть менее, чем полностью (Math.random() — криптографически небезопасен).

S>В общем, либо вы чего-то недоговариваете, либо у вас беспочвенная паранойя. Нужно понимать, что уязвимости клиента вы в любом случае не контролируете (кроме случая, когда клиентом является ваш же веб-сайт), поэтому вам нужно сосредоточиться на том, как дать API, позволяющий безопасную реализацию клиента. Реализовать API, запрещающий реализацию небезопасного клиента всё равно невозможно.

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

C>>Или это могут быть не пользователи вообще, а другие чувствительные к безопасности объекты.

S>У всех чувствительных к безопасности объектов работают права доступа. Это и есть основной способ защиты от злоупотреблений. Сценарий конфликта идентификаторов приводит в REST к "кто последний, того и тапки", поэтому хитровывернутые пользователи, предсказывающие идентификаторы, просто теряют "свои" объекты.
Ну вот как быть в случае с "заранее создали пользователя"?

Кстати, это может быть и другой объект. К примеру, создали документ первым запросом, а потом в него загрузили секретное содержимое. С правами доступа тоже всё ОК — пользователь-враг сам создал документ и имеет к нему полный доступ. Админ тоже имеет полный доступ, так как он админ.
Sapienti sat!
Re[20]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sinclair Россия https://github.com/evilguest/
Дата: 10.02.14 08:18
Оценка:
Здравствуйте, dimgel, Вы писали:

D>Выдавить-то не проблема, но для этого этот набор надо сначала знать.

Ну вот я вам рассказываю
D>Упс, первый раз слышу. Кто и зачем этого может пожелать? (Смутно помню стародавние срачи про производительность индексов, но мне это всё казалось слишком далёким от реальной жизни простых смертных.)
В среднем раз в 3 месяца на нашем форуме, и 1 раз в месяц на sql.ru поднимается этот вопрос — очередной нуб удивляется, что rollback транзакции с insert приводит к появлению дырки в identity.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[15]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sinclair Россия https://github.com/evilguest/
Дата: 10.02.14 08:19
Оценка:
Здравствуйте, dimgel, Вы писали:

D>Я дописываю версию (а точнее, mtime и/или filesize и/или md5 — в зависимости от языка) в Query String.

Для ресурсов-из-сборок в ASP.NET делается точно так же.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[15]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sinclair Россия https://github.com/evilguest/
Дата: 10.02.14 08:24
Оценка:
Здравствуйте, dimgel, Вы писали:

D>Ctrl+F5 рулит, гыгы.

Не, в случае 302 даже Shift-Ctrl-F5, а также перезагрузка машины никак не помогают.

D>Ещё можно сделать всё на ажаксе, а в корень прогружать пустую bootstrap-страницу.

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

D>А вообщеЮ в HTTP кеширование несколько противоестественное, потому что решение принимает клиент, который может вообще игнорировать заголовки сервера

Кэширование в HTTP на удивление хорошее (с учётом даты разработки).

D>причём в обе стороны: Ctrl+F5 чтобы всегда грузить, или вон system.console со своей Оперой (на редкость беспредельничающий браузер, и был таковым с самого начала: "ускорение загрузки" за счёт наплевательского отношения к протоколу).

Это, по большому счёту, проблемы клиента. Сила кэширования HTTP — в прозрачности. То есть я могу поставить между клиентом и сервером squid, или nginx, или lightthpd, и получить performance boost "на ровном месте" без вложений в инфраструктуру на клиенте или на сервере. Для произвольного RPC мне придётся во-первых писать умного прокси с нуля, во-вторых придётся долго ловить в нём глюки.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[21]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sinclair Россия https://github.com/evilguest/
Дата: 10.02.14 08:31
Оценка:
Здравствуйте, Cyberax, Вы писали:
C>Так и где здесь REST? Вижу обычный RPC.
Там же, где и всегда. В отличие от RPC, транзакции идемпотентны, поэтому в случае сбоя я могу спокойно выполнять повторный PUT, не боясь второго перевода.

C>SOAP был бы проще, уже почти жалеем, что не выбрали его. Заодно меньше проблем с валидацией схемы данных с ним.

Оппа, недописал — есть JavaScript библиотеки с поддержкой WS-ReliableMessaging?


C>Клиент — на JS.

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

C>Не веришь, что бывают уязвимые GUID'ы? Вот пожалуйста, почитай тред на SO: http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript — ВСЕ примеры оттуда уязвимы чуть менее, чем полностью (Math.random() — криптографически небезопасен).

Вы сами читали по ссылке? Во-первых, там есть пример с криптостойким генератором. Во-вторых, между "криптографически небезопасен" и "уязвим" — пропасть. Пример с подмешиванием таймстэмпа делает предсказание идентификатора нереализуемым.

C>Мы делаем такой API, чтобы его вообще нельзя было неправильно использовать. Так как очень большие риски для нас, в том числе и денежные.

1. Такого API не бывает.
2. Возможности правильно/неправильно использовать не зависят от выбора между REST и RPC.

C>Ну вот как быть в случае с "заранее создали пользователя"?

Я же написал ниже.

C>Кстати, это может быть и другой объект. К примеру, создали документ первым запросом, а потом в него загрузили секретное содержимое. С правами доступа тоже всё ОК — пользователь-враг сам создал документ и имеет к нему полный доступ. Админ тоже имеет полный доступ, так как он админ.

При публикации (тем более в первый раз) секретного содержимого нужно обнулять права доступа к документу. Это сходу решает все ваши несуществующие проблемы угона ID.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[22]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Cyberax Марс  
Дата: 10.02.14 08:48
Оценка:
Здравствуйте, Sinclair, Вы писали:

C>>Так и где здесь REST? Вижу обычный RPC.

S>Там же, где и всегда. В отличие от RPC, транзакции идемпотентны, поэтому в случае сбоя я могу спокойно выполнять повторный PUT, не боясь второго перевода.
Так нету буквы R — Representational. Обычный RPC есть.

C>>SOAP был бы проще, уже почти жалеем, что не выбрали его. Заодно меньше проблем с валидацией схемы данных с ним.

S>Оппа, недописал — есть JavaScript библиотеки с поддержкой WS-ReliableMessaging?
Оно руками реализуется в несколько строк (на клиенте).

C>>Клиент — на JS.

S>Тогда вообще проблемы нет. Пишете клиента сами, и избегаете шансов нарваться на идиода.
У нас модель такая — на нашей платформе пишутся приложения, мы приложениям даём API.

C>>Не веришь, что бывают уязвимые GUID'ы? Вот пожалуйста, почитай тред на SO: http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript — ВСЕ примеры оттуда уязвимы чуть менее, чем полностью (Math.random() — криптографически небезопасен).

S>Вы сами читали по ссылке? Во-первых, там есть пример с криптостойким генератором. Во-вторых, между "криптографически небезопасен" и "уязвим" — пропасть. Пример с подмешиванием таймстэмпа делает предсказание идентификатора нереализуемым.
Читал. Извиняюсь, что не заметил пример с криптостойким ID — он потерялся на фоне уязвимых примеров.

Math.random() угадывается из соседней вкладки браузера, например. И подмешивание timestamp'а не решает ничего, так как идентификаторов можно насоздавать заранее тонну.

C>>Мы делаем такой API, чтобы его вообще нельзя было неправильно использовать. Так как очень большие риски для нас, в том числе и денежные.

S>1. Такого API не бывает.
S>2. Возможности правильно/неправильно использовать не зависят от выбора между REST и RPC.
У Amazon'а примерно такой API есть — его неправильно использовать просто нельзя.

C>>Кстати, это может быть и другой объект. К примеру, создали документ первым запросом, а потом в него загрузили секретное содержимое. С правами доступа тоже всё ОК — пользователь-враг сам создал документ и имеет к нему полный доступ. Админ тоже имеет полный доступ, так как он админ.

S>При публикации (тем более в первый раз) секретного содержимого нужно обнулять права доступа к документу. Это сходу решает все ваши несуществующие проблемы угона ID.
Такими темпами сброс прав надо на каждую операцию будет делать.
Sapienti sat!
Re[17]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sharov Россия  
Дата: 10.02.14 08:59
Оценка:
Здравствуйте, Jack128, Вы писали:


J>А зачем предсказывать?? ставишь снифер клиенту1 и видишь, что тот обращается по урлу www.example.com/api/users/F889A953B7C543AB82762A2E02E299BF вот те гуид и есть. Другое дело, что если "клиент 2 (непривилегированный)" может обресетить пароль, то это вообще какая та странная безопасность. И никакими тикитами с сервера тут не защитится.


А https не спасет от этого? Я понимаю, что урлу можно поглядеть, а если гуид
передавать в заголовке запроса( ну в каком-нибудь там...)?
Кодом людям нужно помогать!
Re[23]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 10.02.14 09:04
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>>>SOAP был бы проще, уже почти жалеем, что не выбрали его. Заодно меньше проблем с валидацией схемы данных с ним.

S>>Оппа, недописал — есть JavaScript библиотеки с поддержкой WS-ReliableMessaging?
C>Оно руками реализуется в несколько строк (на клиенте).

reliable messaging должен поддерживаться обоими сторонами, т.е. это реализация определенных гарантий. Клиент сам по себе не может ничего гарантировать.
Re[24]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Cyberax Марс  
Дата: 10.02.14 09:25
Оценка:
Здравствуйте, Sinclair, Вы писали:

C>>Так нету буквы R — Representational. Обычный RPC есть.

S>C чего это нету?
Где там именно Representational?

C>>Оно руками реализуется в несколько строк (на клиенте).

S>А можно убедительную ссылку?
Его аналог у нас столько и занял.

C>>У нас модель такая — на нашей платформе пишутся приложения, мы приложениям даём API.

S>И? Как это противоречит отдаче JavaScript Client Library?
Свои местечковые библиотеки.

S>Не понимаю. Можно подробнее? Вы предполагаете, что идиот-пользователь откроет параллельно со страничкой клиента, написанной идиотом-программистом, страничку, написанную злоумышленником? И при этом есть какая-то уязвимость в виде XSS, которая позволит злой страничке взаимодействовать с доброй?

S>Интересно.
Предположим, что атакующий имеет доступ на уровне пользователя. Он делает страничку, заманивает туда админа. Страничка используется для угадывания seed'а в Math.random'а — работает в IE и FireFox. Угаданный seed отсылается зловредному скрипту на сервере, контролируемом врагом.

Затем враг будет в течение некоторого времени уметь угадывать UUID'ы, которые сгенерирует браузер админа в соседних вкладках. Далее вопрос в том, как админа попросить сделать небезопасное действие.

И это мы ещё не рассматриваем специально зловредные приложения.

C>>И подмешивание timestamp'а не решает ничего, так как идентификаторов можно насоздавать заранее тонну.

S>Ага. И никто не заметит несколько сот тысяч пользователей, созданных заранее?
А 100500 документов могут и не заметить. Их ещё и удалить потом можно. Или заметят тогда, когда уже будет поздно.

Ну и опять же, timestamp могут и забыть подмешать.

S>С учётом даже пятимиллисекундного разрешения, нужно создавать по 200 пользователей в секунду, чтобы успеть перехватить следующего.

Да, и что?

C>>У Amazon'а примерно такой API есть — его неправильно использовать просто нельзя.

S>REST?
Да.

C>>Такими темпами сброс прав надо на каждую операцию будет делать.

S>Пока причин так делать не видно. Сброс прав при создании нового объекта — вполне естественная вещь, и я не понимаю, почему она вызывает какие-либо проблемы. Сброс прав при переводе несекретного объекта в секретный — минимальное требование безопасности. Во всех остальных случаях (внесение изменений в объект) я не вижу ни самой проблемы, ни её специфики для REST.
Ну вот второй пример — создали объект "документ" (с метаданными), а вторым запросом установили для него содержимое. Нужно ли сбрасывать права при втором запросе?
Sapienti sat!
Re[14]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 10.02.14 09:36
Оценка:
Здравствуйте, Sinclair, Вы писали:

Большое спасибо за развернутый ответ. Я сейчас только начал делать сайт на MVC для доступа клиента к своим данным на основании авторизации и забитого в users его ID. И читая эту ветку пришел к ужасу по поводу кэширования.
Кстати можешь скинуть ссылку где в MVC прописывать параметры кэширования.
http://xmlhack.ru/texts/06/doing-http-caching-right/doing-http-caching-right.html

Понятно что можно через Response.Headers, а может через config прописывать.
А то сейчас кроме работы, еще и MVC http://metanit.com/sharp/mvc/3.5.php изучаю, CSS, Оuery итд. Буду благодарен ссылочкам на русскоязычные сайты. Еще раз спасибо з развернутый ответ.
и солнце б утром не вставало, когда бы не было меня
Re[25]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sinclair Россия https://github.com/evilguest/
Дата: 10.02.14 09:46
Оценка:
Здравствуйте, Cyberax, Вы писали:
C>Где там именно Representational?
Вы сначала определите смысл, который вы вкладываете в термин Representational.
C моей точки зрения, транзакция как объект ничем не хуже объекта "счёт".
В большом количестве случаев она есть "и так" в предметной области — например, в финансовом учёте есть понятие "хоз.операция", в которой участвуют оба счёта. Примером операции, затрагивающей более 2х объектов, является ревизия в SVN/CVS. То есть это не просто "синтетическая" штука, придуманная исключительно для обхода проблемы отсутствия WS-Transactions, а первоклассная сущность, со сценариями "дай мне список ревизий" по всяким разным критериям.

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

C>Его аналог у нас столько и занял.

Аналог, надо полагать, на REST? Потому что стандартный WS-ReliableMessaging вы ни в несколько строк, ни в несколько тысяч строк на JS не реализуете.

C>Свои местечковые библиотеки.

Не понимаю. Для чего вам "свои местечковые библиотеки"? Такое ощущение, что вы хотите создать проблему, а не решить её.

C>Предположим, что атакующий имеет доступ на уровне пользователя. Он делает страничку, заманивает туда админа. Страничка используется для угадывания seed'а в Math.random'а — работает в IE и FireFox. Угаданный seed отсылается зловредному скрипту на сервере, контролируемом врагом.

Это — хорошая идея.

C>Затем враг будет в течение некоторого времени уметь угадывать UUID'ы, которые сгенерирует браузер админа в соседних вкладках.

Не, не будет. Потому, что к выходу Math.Random() (который сервер врага умеет предсказать) подмешивается timestamp. Заранее неизвестно два параметра:
— когда именно админ соберётся создавать следующего пользователя / документ
— сколько обращений к math.Random произойдёт до создания следующего пользователя/документа.
То есть, грубо говоря, вам нужно взять следующие 100 случайных чисел, взять следующие 720000 таймстампов, и для всех перемешиваний создать пользователей. Т.е. создать 72 миллиона пользователей, чтобы угнать пользователя, которого админ создаст в течение следующего часа. Служба безопасности сервиса должна быть специально подкуплена, чтобы не заметить такую активность. С учётом sensitivity данных, с которыми вы работаете, пользователь наверняка регистрируется не через фейсбук, а достаточно серьёзным способом, подразумевающим возможность идентификации. Так что дальше такого активиста сдаём в отдел К и он садится по статьям 272/273 УК на время, достаточное для гарантии безопасности данных.

C>Далее вопрос в том, как админа попросить сделать небезопасное действие.

C>И это мы ещё не рассматриваем специально зловредные приложения.
А какие же вы рассматриваете? Именно что зловредные.

C>А 100500 документов могут и не заметить. Их ещё и удалить потом можно. Или заметят тогда, когда уже будет поздно.

Тогда предотвращайте угон документов при помощи контроля прав.
C>Ну и опять же, timestamp могут и забыть подмешать.
Если клиент — идиот, то он всегда может выстрелить себе в ногу.
S>>REST?
C>Да.
Ну, даже если поверить, что этот API нельзя неправильно использовать (например, тупо храня shared secret в общедоступном месте), то это одно уже доказывает независимость возможности такого API от REST/RPC дилеммы.

C>Ну вот второй пример — создали объект "документ" (с метаданными), а вторым запросом установили для него содержимое. Нужно ли сбрасывать права при втором запросе?

Если вы точно знаете, что новое содержимое (в отличие от старого) является classified, то да. А если нет, то достаточно было сбросить права при первом запросе. Вроде не rocket science?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[16]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: dimgel Россия https://github.com/dimgel
Дата: 10.02.14 10:07
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Кэширование в HTTP на удивление хорошее


Да я в общем-то и не спорю, т.к. пытался прикинуть альтернативные варианты — и ничего путного не прикинулось.
Re[25]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 10.02.14 16:48
Оценка:
Здравствуйте, Cyberax, Вы писали:

S>>Не понимаю. Можно подробнее? Вы предполагаете, что идиот-пользователь откроет параллельно со страничкой клиента, написанной идиотом-программистом, страничку, написанную злоумышленником? И при этом есть какая-то уязвимость в виде XSS, которая позволит злой страничке взаимодействовать с доброй?

S>>Интересно.
C>Предположим, что атакующий имеет доступ на уровне пользователя. Он делает страничку, заманивает туда админа. Страничка используется для угадывания seed'а в Math.random'а — работает в IE и FireFox. Угаданный seed отсылается зловредному скрипту на сервере, контролируемом врагом.
Добавьте anti forgery token и будет вам счастье.
Re[26]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Cyberax Марс  
Дата: 10.02.14 18:11
Оценка:
Здравствуйте, gandjustas, Вы писали:

C>>Предположим, что атакующий имеет доступ на уровне пользователя. Он делает страничку, заманивает туда админа. Страничка используется для угадывания seed'а в Math.random'а — работает в IE и FireFox. Угаданный seed отсылается зловредному скрипту на сервере, контролируемом врагом.

G>Добавьте anti forgery token и будет вам счастье.
Как он поможет?
Sapienti sat!
Re[27]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 10.02.14 19:30
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Здравствуйте, gandjustas, Вы писали:


C>>>Предположим, что атакующий имеет доступ на уровне пользователя. Он делает страничку, заманивает туда админа. Страничка используется для угадывания seed'а в Math.random'а — работает в IE и FireFox. Угаданный seed отсылается зловредному скрипту на сервере, контролируемом врагом.

G>>Добавьте anti forgery token и будет вам счастье.
C>Как он поможет?

Поможет не подделать запрос. Ибо кроме seed нужно будет получить token, а это сможет сделать только аутентифицированный пользователь. Конечно нужна будет проверка прав на сервере.
Re[17]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sinclair Россия https://github.com/evilguest/
Дата: 11.02.14 06:23
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>У меня статья есть на эту тему, вдруг пригодится: http://gandjustas.blogspot.ru/2013/02/aspnet-mvc.html

Отличная статья. Если я правильно понимаю, то подразумеваемый способ борьбы с conditional Get всё же другой.
У тебя идёт ручное управление кэшированием: ты кладёшь ответ в кэш вручную, и вручную же проверяешь, что там не так.
В теории, вся семантика последующей работы с кэшем уже реализована в самом ASP.NET.
То есть, достаточно выставить респонсу подходящий cacheability, зарегистрировать зависимости в response.AddCacheDependency() (например, зависимость от результата SQL-запроса), и всё будет работать само.
Логика — примерно такая: если приходит запрос на URL, который уже есть в кэше ASP.NET, то кэш его проверяет на предмет валидности, дёргая HasChanged у всех депенденсей, и если всё в порядке, то отдаёт ответ из кэша, не вызывая код контроллера. А если в запросе присутствует If-Modified-Since, то он ещё и отдаёт 304 вместо контента.

К сожалению, на практике я так и не дошёл до полной реализации этого подхода. Если нет подводных камней, то код твоего метода CartSummary должен сократиться в разы.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[18]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 11.02.14 07:14
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, gandjustas, Вы писали:


G>>У меня статья есть на эту тему, вдруг пригодится: http://gandjustas.blogspot.ru/2013/02/aspnet-mvc.html

S>Отличная статья. Если я правильно понимаю, то подразумеваемый способ борьбы с conditional Get всё же другой.
S>У тебя идёт ручное управление кэшированием: ты кладёшь ответ в кэш вручную, и вручную же проверяешь, что там не так.
S>В теории, вся семантика последующей работы с кэшем уже реализована в самом ASP.NET.
S>То есть, достаточно выставить респонсу подходящий cacheability, зарегистрировать зависимости в response.AddCacheDependency() (например, зависимость от результата SQL-запроса), и всё будет работать само.
S>Логика — примерно такая: если приходит запрос на URL, который уже есть в кэше ASP.NET, то кэш его проверяет на предмет валидности, дёргая HasChanged у всех депенденсей, и если всё в порядке, то отдаёт ответ из кэша, не вызывая код контроллера. А если в запросе присутствует If-Modified-Since, то он ещё и отдаёт 304 вместо контента.

S>К сожалению, на практике я так и не дошёл до полной реализации этого подхода. Если нет подводных камней, то код твоего метода CartSummary должен сократиться в разы.


Я все хочу пост на тему dependency сделать. Увы там много подводных камней, sqldependency я пытался завести целый день. Кроме того, для распределенного кеша надо будет свой cachedependency класс делать, с гораздо более сложным кодом.
Re[2]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Vzhyk  
Дата: 12.02.14 10:24
Оценка:
2/12/2014 12:33 PM, dimgel пишет:

> Дожили. В кои-то веки профильную тему завёл — и ту в КСВ перенесли.

Странный ты. Форум просто в КСВ плавно перетекает, ибо тут осталось
единственное место где можно что-то обсудить, поспорить, столкнутся
взглядами и не очень толерастно.
Posted via RSDN NNTP Server 2.1 beta
Re[19]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sinclair Россия https://github.com/evilguest/
Дата: 13.02.14 03:37
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Я все хочу пост на тему dependency сделать.

Было бы здорово.
G>Увы там много подводных камней, sqldependency я пытался завести целый день. Кроме того, для распределенного кеша надо будет свой cachedependency класс делать, с гораздо более сложным кодом.
Нутром чую, что можно обойтись без SQLDependency, зато прикрутить linq.
То есть идея — в том, что для для SQL запроса Х автоматически получать запрос Y, который возвращает либо хеш (ETag), либо дату последней модификации (timestamp).
Но это надо подробно прорабатывать.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[20]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 13.02.14 06:35
Оценка:
Здравствуйте, Sinclair, Вы писали:

G>>Увы там много подводных камней, sqldependency я пытался завести целый день. Кроме того, для распределенного кеша надо будет свой cachedependency класс делать, с гораздо более сложным кодом.

S>Нутром чую, что можно обойтись без SQLDependency, зато прикрутить linq.
S>То есть идея — в том, что для для SQL запроса Х автоматически получать запрос Y, который возвращает либо хеш (ETag), либо дату последней модификации (timestamp).
S>Но это надо подробно прорабатывать.
А поподробнее?

Встроенный SqlCacheDependency — реализация вокруг System.Data.SqlClient.SqlDependency, построенная на polling в отдельном потоке или SQL Notifications. Pooling неинтересен по понятным причинам, а для Notifications много ограничений — http://msdn.microsoft.com/library/ms181122.aspx. SqlCacheDependency вообще позволяет только имя таблицы указать.
Как автоматически сделать из произвольного Linq запроса пригодный для SqlDependeuncy я не представляю. А писать свой CacheDependency класс как-то сложно.
Делать зарос в базу для проверки каждый раз будет крайне неэффективно.
Re[21]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sinclair Россия https://github.com/evilguest/
Дата: 13.02.14 08:06
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>А поподробнее?

Предположим, мы решаем задачу с нуля — нет ни кэш инфраструктуры, ни Linq, ни MVC.
Как мы будем действовать?
Например, мы можем добавить в интересующие нас таблицы поля LastUpdateTimestamp, оборудованные триггерами на апдейт. Тогда можно понять, изменился ли результат запроса, при помощи select max(LastUpdateTimestamp) from ...

Теперь, посмотрев на такую ручную реализацию, можно попробовать её генерализовать. До linq это было практически нереализуемо, т.к. по тексту стейтмента разобраться, от чего зависит его результат, нереалистично.
А Linq потенциально позволяет нам разобраться во всём.

G>Встроенный SqlCacheDependency — реализация вокруг System.Data.SqlClient.SqlDependency, построенная на polling в отдельном потоке или SQL Notifications. Pooling неинтересен по понятным причинам, а для Notifications много ограничений — http://msdn.microsoft.com/library/ms181122.aspx. SqlCacheDependency вообще позволяет только имя таблицы указать.

Вот именно.
G>Как автоматически сделать из произвольного Linq запроса пригодный для SqlDependeuncy я не представляю. А писать свой CacheDependency класс как-то сложно.
Ну вот мне кажется, что должен быть свой.
G>Делать зарос в базу для проверки каждый раз будет крайне неэффективно.
Не факт. Во-первых, даже если мы подготовили полный результат, и только теперь убедились, что у клиента такой уже есть, отдать 304 всё ещё лучше с точки зрения трафика. Во-вторых, потенциально запрос, вычисляющий только LastModifiedTimestamp или только ETag может оказаться эффективнее полного запроса. Ну, а главное — альтернативы-то никакой нет. Только если ставить между SQL и кодом приложения какой-то ещё кэш, который поддерживает механизм нотификаций или ещё какой-то метод быстрее выяснить, что некоторый запрос устарел, на основе знаний о привнесённых изменениях.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[22]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: dimgel Россия https://github.com/dimgel
Дата: 13.02.14 10:12
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Только если ставить между SQL и кодом приложения какой-то ещё кэш, который поддерживает механизм нотификаций или ещё какой-то метод быстрее выяснить, что некоторый запрос устарел, на основе знаний о привнесённых изменениях.


А это кстати идея. Зачем "между", если можно отдельным слоем в само приложение. Тут неподалёку про DAL и BL спрашивали — так вот у меня есть и то, и другое, и ответственность DAL — как раз кеши (моя вещь, как хочу — так и называю ). Надо будет чутка расширить их функционал.
Re[23]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Sinclair Россия https://github.com/evilguest/
Дата: 13.02.14 10:27
Оценка:
Здравствуйте, dimgel, Вы писали:
D>А это кстати идея. Зачем "между", если можно отдельным слоем в само приложение. Тут неподалёку про DAL и BL спрашивали — так вот у меня есть и то, и другое, и ответственность DAL — как раз кеши (моя вещь, как хочу — так и называю ). Надо будет чутка расширить их функционал.
Тут главное — зависимости отследить.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[24]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: dimgel Россия https://github.com/dimgel
Дата: 13.02.14 10:31
Оценка:
Здравствуйте, Sinclair, Вы писали:

D>>А это кстати идея. Зачем "между", если можно отдельным слоем в само приложение. Тут неподалёку про DAL и BL спрашивали — так вот у меня есть и то, и другое, и ответственность DAL — как раз кеши (моя вещь, как хочу — так и называю ). Надо будет чутка расширить их функционал.

S>Тут главное — зависимости отследить.

Вот поэтому я и выношу все кеши в отдельный прокси-слой. А та идейка от IT, на недопонимание которой я в своё время жаловался (≈"я кеширую не entities, а результаты вызовов методов"), похоже по этой же причине и недопонимается.
Re[22]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 13.02.14 13:32
Оценка:
Здравствуйте, Sinclair, Вы писали:

G>>Делать зарос в базу для проверки каждый раз будет крайне неэффективно.

S>Не факт. Во-первых, даже если мы подготовили полный результат, и только теперь убедились, что у клиента такой уже есть, отдать 304 всё ещё лучше с точки зрения трафика. Во-вторых, потенциально запрос, вычисляющий только LastModifiedTimestamp или только ETag может оказаться эффективнее полного запроса. Ну, а главное — альтернативы-то никакой нет. Только если ставить между SQL и кодом приложения какой-то ещё кэш, который поддерживает механизм нотификаций или ещё какой-то метод быстрее выяснить, что некоторый запрос устарел, на основе знаний о привнесённых изменениях.

Я такой подход проверял. Получилось на небольшой нагрузке, пока все данные находятся гарантированно в кеше SQL, работает быстро. А как только память кончается, то получается что на каждый запрос пользователя гарантированно в базу летит как минимум один "тяжелый" запрос, ибо нужно собрать данные из нескольких связанных таблиц. База начинает загибаться при таком подходе, а веб-серверы отдыхать.

Следующая идея была — вычислять дату последнего изменения в момент изменения и хранить в базе. Потом из базы перехало в распределенный кеш, ну и в итоге получится middleware, который к базе не имеет отношения. К нему кстати прикрутили в итоге watchdog, чтобы синхронизировать данные из базы с отметками в кеше. По сути был изобретен поллинг, только через одно место. Но даже поллинг сильно снижал нагрузку по сравнению с первоначальным вариантом. Нотификации должны сократить нагрузку еще сильнее при правильном использовании, так как на одно изменение может прилетать одна нотификация
Re[7]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Ночной Смотрящий Россия  
Дата: 16.02.14 22:04
Оценка:
Здравствуйте, fddima, Вы писали:

F>3-rd party товарищи умудряющтся отвечать NaN в JSON, что никак недопустимо.


JSON != REST. Я, к примеру, предпочитаю по ряду причин старый добрый XML, а JSON появляется только тогда, когда с той стороны в основном JS, да и то не всегда. Ну и есть же тот же WebAPI, который сам отдаст клиенту то, что он хочет.
Re[19]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: dimgel Россия https://github.com/dimgel
Дата: 21.02.14 23:54
Оценка:
Здравствуйте, netch80, Вы писали:

N>Но REST в описанном виде рассчитан в том числе и на участие промежуточных HTTP proxy с локальными кэшами (типа знаменитого squid, или nginx frontend). (Прокси не обязан быть публичным, он может быть и внутренним только для целей данного сервиса — но он всё равно может быть.) Предположим, что содержимое ответа /my/contacts не настолько секретно, чтобы не доверять его промежуточным автоматическим участникам. Как ты сделаешь различение, что есть /my/contacts для клиента 1 и /my/contacts для клиента 2? Прокси не в состоянии это различить. Максимум, что ты можешь — сказать ему не кэшировать. Но даже в этом случае прокси имеет право соптимизировать, если идут одновременные запросы на один и тот же URL от разных участников и один из ответов ещё не отдан до конца. Авторизация, согласно RFC 2616 и тому подобным, не влияет на кэширование.


Вопрос. Не так давно где-то краем уха я слышал, что в HTTP 2.0 будет форсировано использование SSL, т.е. это будет всегда https. ХЗ сколько в этом правды, но если у меня весь сайт (как минимум личный кабинет и API) будут под https, все промежуточные прокси пролетают как фанера над парижем, я так понимаю? И как с этим разработчики REST API живут? Не юзают SSL?

(Кроме того, несколько непонятна эта вот ортогональность авторизации и кеширования. Т.е. на концептуальном уровне разумно, но практически — )
Re[2]: know-your-http-well
От: dimgel Россия https://github.com/dimgel
Дата: 23.02.14 13:54
Оценка:
Здравствуйте, Mamut, Вы писали:

M>1. Курить эту диаграмму, учить наизусть и знать, как «Отче Наш»: https://raw.github.com/for-GET/http-decision-diagram/master/httpdd.png (Она намного более полная и вменяемая, чем известная диаграмма Webmachine).


Что-то у меня такое чувство, что "отче наш" это должно быть для разработчиков HTTP-сервера, а прикладному программисту хватит doGet(), doPost(), doOptions(), doPut(), doDelete() из Servlet API.

M>(да, HTTP-заголовки существуют не просто для того, чтобы на них тупо смотреть).


Спасибо, кэп.
Re[3]: know-your-http-well
От: Mamut Швеция http://dmitriid.com
Дата: 24.02.14 08:26
Оценка:
M>>1. Курить эту диаграмму, учить наизусть и знать, как «Отче Наш»: https://raw.github.com/for-GET/http-decision-diagram/master/httpdd.png (Она намного более полная и вменяемая, чем известная диаграмма Webmachine).

D>Что-то у меня такое чувство, что "отче наш" это должно быть для разработчиков HTTP-сервера, а прикладному программисту хватит doGet(), doPost(), doOptions(), doPut(), doDelete() из Servlet API.


Это только так кажется.

M>>(да, HTTP-заголовки существуют не просто для того, чтобы на них тупо смотреть).


D>Спасибо, кэп.


Вот именно поэтому только doGet и прочими не обойтись. Даже составление и обработка грамотного ETag'а — это уже больше, чем просто doGet()


dmitriid.comGitHubLinkedIn
Re[5]: know-your-http-well
От: Mamut Швеция http://dmitriid.com
Дата: 24.02.14 10:39
Оценка:
M>>Это только так кажется.
M>>Вот именно поэтому только doGet и прочими не обойтись. Даже составление и обработка грамотного ETag'а — это уже больше, чем просто doGet()

D>Возможно. Я планирую плотно заняться обдумыванием генератора REST API (с предварительным ковырянием в чужих, и может даже O'Relly придётся дочитать, т.к. пока что не понятно ни черта) не раньше чем через месяц. А одну книжку осилил заранее, чтобы пока что в фоновом режиме хоть что-то утряслось.


Про REST говорят, что он simple, но никак не easy И это, увы, так


dmitriid.comGitHubLinkedIn
Re[19]: И еще про кэширование
От: Mamut Швеция http://dmitriid.com
Дата: 24.02.14 15:18
Оценка:
N>Но REST в описанном виде рассчитан в том числе и на участие промежуточных HTTP proxy с локальными кэшами (типа знаменитого squid, или nginx frontend).

Про кэширование хорошо тут: http://bizcoder.com/caching-is-hard-draw-me-a-picture


dmitriid.comGitHubLinkedIn
Re[6]: know-your-http-well
От: dimgel Россия https://github.com/dimgel
Дата: 24.02.14 15:38
Оценка:
Здравствуйте, Mamut, Вы писали:

M>Про REST говорят, что он simple, но никак не easy И это, увы, так


А посоветуй, кстати, какой-нить конкретный генератор REST API.
Re[7]: know-your-http-well
От: Mamut Швеция http://dmitriid.com
Дата: 24.02.14 15:40
Оценка:
M>>Про REST говорят, что он simple, но никак не easy И это, увы, так

D>А посоветуй, кстати, какой-нить конкретный генератор REST API.


Смотря, что ты имеешь в виду под генератором REST API


dmitriid.comGitHubLinkedIn
Re[8]: know-your-http-well
От: dimgel Россия https://github.com/dimgel
Дата: 24.02.14 15:44
Оценка:
Здравствуйте, Mamut, Вы писали:

M>Смотря, что ты имеешь в виду под генератором REST API


Понятия не имею. Но успел увидеть краем уха, что такие бывают. Мне надо хоть от чего-то оттолкнуться.
Re[5]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Lonely Dog Россия  
Дата: 06.03.14 08:25
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, dimgel, Вы писали:

D>>Любопытно и доля истины ощущается. Но ограниченность множества глаголов — объективный факт. (Я ХЗ как ты относишься к типу ресурса "контроллер", мне же он кажется натягиванием презерватива на глобус — отход от концептуально правильного REST-а, пригодного в чистом виде — повторюсь — только для ресурсопомоек, в угоду суровой правде жизни.)
S>Спор беспредметен. Во всех предыдущих инкарнациях, REST выигрывал у RPC на его же поле. Я по-прежнему открыт к дискуссии в формате "вот схема RPC API, и по-моему это плохо воспроизводится в REST". В ответ на что я предъявляю схему REST-сервиса, который делает то же самое, плюс решает пару проблем, о которых автор RPC по наивности не подумал. Либо я соглашаюсь, что да, таки в данном случае RPC лучше, и мы наконец-то имеем хоть один пример, где RPC выигрывает.
Тогда не в порядке спора и попыток переубедить. Объясните как реализовать с помощью REST процедуру логона. Ну точнее не реализовать, а какие API (ресурсы должны быть). Типичный сценарий:
1. Клиент начинает сессию (передает имя пользователя, и способ аутентификации).
2. Сервер поднимает плагин, отвечающий за этот способ и отдает ему имя пользователя.
3. Плагин генерит некие данные (challenge), отдает серверу, а он отдает клиенту.
4. Клиент запрашивает у пользователя его секретные данные (пароль, палец и пр), отсылает серверу.
5. Сервер передает эти данные плагину, который может:
a. Сказать, что логон успешен.
b. Сказать, что логон не успешен.
с. Затребовать новые данные.


Заранее спасибо.
Re[6]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Mamut Швеция http://dmitriid.com
Дата: 06.03.14 09:58
Оценка:
LD>Тогда не в порядке спора и попыток переубедить. Объясните как реализовать с помощью REST процедуру логона. Ну точнее не реализовать, а какие API (ресурсы должны быть). Типичный сценарий:

LD>1. Клиент начинает сессию (передает имя пользователя, и способ аутентификации).

LD>2. Сервер поднимает плагин, отвечающий за этот способ и отдает ему имя пользователя.
LD>3. Плагин генерит некие данные (challenge), отдает серверу, а он отдает клиенту.
LD>4. Клиент запрашивает у пользователя его секретные данные (пароль, палец и пр), отсылает серверу.
LD>5. Сервер передает эти данные плагину, который может:
LD> a. Сказать, что логон успешен.
LD> b. Сказать, что логон не успешен.
LD> с. Затребовать новые данные.

Ну, что-то в такое (писал после бессонной ночи на коленке, и вообще лучше посмотреть на OAuth, например, который что-то подобное реализует)

POST /authorization
> Authorization: SomeAuth "some-string"
> Content-Type: application/vnd.example.com-auth-v1+json
{
    "login": "Bob"
}
< 401 Unauthorized
< WWW-Authenticate: SomeAuth realm="myRealm", credentials="1234567890"

POST /authorization
> Authorization: SomeAuth "some-string", credentials="1234567890"
> Content-Type: application/vnd.example.com-auth-v1+json
{
    "login": "Bob",
    "data": [...]
}


Логин успешен:
< 302 Temporary Redirect
< Location: /куда/нибудь


Логин неуспешен:
< 401 Unauthorized
< WWW-Authenticate: SomeAuth realm="myRealm",
                    credentials="0987651",
                    someauth_error="invalid login"


Еще данные:
Логин неуспешен:
< 401 Unauthorized
< WWW-Authenticate: SomeAuth realm="myRealm",
                    credentials="0987651",
                    someauth_error="more data needed"


dmitriid.comGitHubLinkedIn
Re[6]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: Ночной Смотрящий Россия  
Дата: 06.03.14 13:10
Оценка:
Здравствуйте, Lonely Dog, Вы писали:

LD>Тогда не в порядке спора и попыток переубедить. Объясните как реализовать с помощью REST процедуру логона.


Это простой вопрос. Стандартными для HTTP средствами.
Re[7]: [давненько мы за REST не срались] Paradigm mismatch is unavoidable!
От: dimgel Россия https://github.com/dimgel
Дата: 09.03.14 10:03
Оценка:
Здравствуйте, Mamut, Вы писали:

LD>>Тогда не в порядке спора и попыток переубедить. Объясните как реализовать с помощью REST процедуру логона. Ну точнее не реализовать, а какие API (ресурсы должны быть).

M>Ну, что-то в такое (писал после бессонной ночи на коленке, и вообще лучше посмотреть на OAuth, например, который что-то подобное реализует)

Чёт я недопонял, зачем в REST API отдельная точка входа для login.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.