Здравствуйте, Cyberax, Вы писали:
C>Попытка номер 1 — POST-метод. Не работает — если теряем соединение после окончания метода, то у нас потеря документа. C>Попытка номер 2 — POST-метод с уникальным GUID'ом для tracking'а, передаваемым в запросе. Не работает из-за вопросов безопасности. C>Попытка номер 3 — разбиваем на два этапа: получение уникального GUID'а первым запросом, а потом использование этого GUID'а во втором.
Надо было начинать с идемпотентного PUT, используя GUID, который вполне безопасен.
C>А ещё из практических встреч — проблемы с кодировками запросов.
Непонятно, откуда они берутся. Вопрос кодировок в вебе стандпртизован вдоль и поперек — уж всяко лучше, чем в наколенных протоколах. C>Ну и что дальше делать? Получается, что надо темпоральную базу иметь чуть ли не для всех доменных объектов при богатом REST-API. Или кидать в таком случае исключения, что не есть хорошо — блокировок нет, а сценарии с оптимистической блокировкой без атомарности получаются жуткими.
не понимаю вашу проблему. Темпоральная база нафиг не нужна. Достаточно хранить актуальную версию. Дальше стандартный подход — reload and repeat.
остальное допишу попожже.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
C>>Попытка номер 1 — POST-метод. Не работает — если теряем соединение после окончания метода, то у нас потеря документа. C>>Попытка номер 2 — POST-метод с уникальным GUID'ом для tracking'а, передаваемым в запросе. Не работает из-за вопросов безопасности. C>>Попытка номер 3 — разбиваем на два этапа: получение уникального GUID'а первым запросом, а потом использование этого GUID'а во втором. S>Надо было начинать с идемпотентного PUT, используя GUID, который вполне безопасен.
Небезопасен. Так как источник генерирования GUID'ов может быть небезопасен.
C>>А ещё из практических встреч — проблемы с кодировками запросов. S>Непонятно, откуда они берутся. Вопрос кодировок в вебе стандпртизован вдоль и поперек — уж всяко лучше, чем в наколенных протоколах.
Ага. Именно поэтому в мой сервис иногда данные приходят в cp1251.
S>не понимаю вашу проблему. Темпоральная база нафиг не нужна. Достаточно хранить актуальную версию. Дальше стандартный подход — reload and repeat. S>остальное допишу попожже.
Мне нужно обновить два ресурса. Я делаю update на первый ресурс, а потом update на второй. Но при втором update'е получаю "чувак, ресурс устарел".
Що робыти? Откатить первое изменение, в общем случае нельзя. В SOAP для такой цели, хотя бы, есть WS-Transaction (при всех её недостатках).
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, Mystic, Вы писали:
M>>Это образно
AVK>В лес такие образы. В каком то форуме было правило, как только в топике упоминается Гитлер, топик сразу можно закрывать. В программистских флеймах полный аналог Гитлера — программирование АЭС.
Здравствуйте, Cyberax, Вы писали: S>>Надо было начинать с идемпотентного PUT, используя GUID, который вполне безопасен. C>Небезопасен. Так как источник генерирования GUID'ов может быть небезопасен.
Это очень большая экзотика. В природе traceable GUIDs не встречаются уже очень много лет.
Чтобы выдавать это за недостаток протокола, надо быть более чем слегка параноидальным.
C>Ага. Именно поэтому в мой сервис иногда данные приходят в cp1251.
Неважно, в чём они приходят. Главное, чтобы headers соответстовали.
C>Мне нужно обновить два ресурса. Я делаю update на первый ресурс, а потом update на второй. Но при втором update'е получаю "чувак, ресурс устарел".
Это значит, что границы атомарности объектов были выбраны неправильно. Граница транзакции в REST совпадает с границей объекта. Больше сказать ничего нельзя без конкретных деталей.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
C>>Небезопасен. Так как источник генерирования GUID'ов может быть небезопасен. S>Это очень большая экзотика. В природе traceable GUIDs не встречаются уже очень много лет. S>Чтобы выдавать это за недостаток протокола, надо быть более чем слегка параноидальным.
Хех. Мне приходили GUID'ы вида 000000000000001, 000000000000002 и т.д.
C>>Ага. Именно поэтому в мой сервис иногда данные приходят в cp1251. S>Неважно, в чём они приходят. Главное, чтобы headers соответстовали.
Ага, только вот не всегда.
C>>Мне нужно обновить два ресурса. Я делаю update на первый ресурс, а потом update на второй. Но при втором update'е получаю "чувак, ресурс устарел". S>Это значит, что границы атомарности объектов были выбраны неправильно. Граница транзакции в REST совпадает с границей объекта. Больше сказать ничего нельзя без конкретных деталей.
Так мне нужно два объекта обновить "одновременно". REST это делает крайне тяжёлым.
Здравствуйте, Cyberax, Вы писали:
C>Добавлю ещё: C>6) Отсутствие само-описания типа WSDL для SOAP.
как раз с discoverability в REST всё очень хорошо. Но она рассчитана на человека, а не на автомат. Что, в общем-то, нормально: REST — это подход, а не какой-то конкретный стандарт.
C>7) Нет формальной спецификации — каждый понимает REST по-своему. Из-за этого, клиент практически для любого сервиса приходится писать после долгого вкуривания документации и экспериментов. C>Для SOAP уже всё почти plug&play — я могу взять WSDL, по ней сгенерировать стабы и использовать в почти любом языке.
Если честно, то я не вижу связи. Без документации SOAP-сервис практически полностью бесполезен. Возможность сделать вызов "в любом языке" совершенно бесполезна без понимания, какие именно вызовы делать. Стандартной штукой является наличие "волшебных параметров", которые ссылаются на какие-то другие объекты, без малейшей идеи где идентификаторы этих объектов нужно брать.
RESTful API можно изучать с помощью браузера. Даже если нет вообще никакой документации, то более-менее понятно, какие именно вещи нужно делать.
C>8) Проблема с передачей сложных данных (даже банальный hash map нормально не передаётся) и т.д. Я понимаю, что сразу в таких случаях кричат: "JSON в POST/PUT", но в чём тогда отличие от SOAP?
Нет вообще никакой проблемы с передачей сложных данных. Отличие от SOAP — очень простое: через границу SOAP невозможно передать ссылку на объект. В REST все объекты являются адресуемыми, так что можно передавать URI.
Выбор представления для "сложных данных" — полностью на вас. Можно делать XHTML, XML, JSON или вообще произвольный application/octet-stream. Опять же, REST — это не стандарт. Это подход. На основе REST можно построить стандарт; и постепенно это происходит. Точно так же, как SOAP является результатом стандартизации архитектуры SOA.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
C>>Добавлю ещё: C>>6) Отсутствие само-описания типа WSDL для SOAP. S>как раз с discoverability в REST всё очень хорошо.
Агащаз. Как мне найти все параметры, по которым можно искать объект? Или список необходимых параметров при его создании?
А никак, только читать доку. Кстати, если происходит ошибка (скажем, из-за неправильного параметра) — то "you're out of luck". Стандарта на передачу ошибок тоже нет.
C>>7) Нет формальной спецификации — каждый понимает REST по-своему. Из-за этого, клиент практически для любого сервиса приходится писать после долгого вкуривания документации и экспериментов. C>>Для SOAP уже всё почти plug&play — я могу взять WSDL, по ней сгенерировать стабы и использовать в почти любом языке. S>Если честно, то я не вижу связи. Без документации SOAP-сервис практически полностью бесполезен.
Да ну? Я по WSDL практически всегда могу читать без проблем как работает сервис.
К примеру, наш родной service2.wsdl — что в нём непонятного?
S>Возможность сделать вызов "в любом языке" совершенно бесполезна без понимания, какие именно вызовы делать. Стандартной штукой является наличие "волшебных параметров", которые ссылаются на какие-то другие объекты, без малейшей идеи где идентификаторы этих объектов нужно брать.
Минимальный объём документации необходим, но не сильно большой.
S>RESTful API можно изучать с помощью браузера. Даже если нет вообще никакой документации, то более-менее понятно, какие именно вещи нужно делать.
КАК его изучать?
Где тут discoverability? http://chart.apis.google.com/chart выдаёт 400. http://code.google.com/apis/chart/ перегоняет на http://code.google.com/apis/chart/ — где ты фиг найдёшь доку, так как этот API у них deprecated.
C>>8) Проблема с передачей сложных данных (даже банальный hash map нормально не передаётся) и т.д. Я понимаю, что сразу в таких случаях кричат: "JSON в POST/PUT", но в чём тогда отличие от SOAP? S>Нет вообще никакой проблемы с передачей сложных данных. Отличие от SOAP — очень простое: через границу SOAP невозможно передать ссылку на объект.
Можно. Ровно как и в REST.
S>В REST все объекты являются адресуемыми, так что можно передавать URI.
Неверно. Скажем, я не могу из клиента передать ссылку серверу на мой объект — в мобильном телефоне веб-серверы не работают.
Не говоря уж о том, что это исключительно хрупкий подход.
S>Выбор представления для "сложных данных" — полностью на вас. Можно делать XHTML, XML, JSON или вообще произвольный application/octet-stream. Опять же, REST — это не стандарт. Это подход. На основе REST можно построить стандарт; и постепенно это происходит. Точно так же, как SOAP является результатом стандартизации архитектуры SOA.
Слова "REST — это подход" вообще гнилая отмаза. Примерно как "я стратег, а не тактик" в анекдоте про зайцев и сову.
Спецификации на что? Спецификация на REST это спецификация на HTTP. Другое дело, что поверх SOAP навернули кучу других спецификаций, аналогов коих для REST мало.
... << RSDN@Home 1.2.0 alpha 5 rev. 1530 on Windows 7 6.1.7601.65536>>
Здравствуйте, Cyberax, Вы писали:
C>Здравствуйте, Sinclair, Вы писали:
C>>>2) Нет возможности нормально делать диалоги — их приходится всё время эмулировать. Криво. Это самое бесящее. S>>Не очень понятно, что такое "диалоги". Вас интересует stateful сессия? Да, её приходится эмулировать. S>>Это оборотная сторона REST. Зато эти сессии появляются только там, где необходимо, а не там, где случайно получилось. C>Вот ситуация — надо создать документ. В одном экземпляре.
C>Попытка номер 1 — POST-метод. Не работает — если теряем соединение после окончания метода, то у нас потеря документа. C>Попытка номер 2 — POST-метод с уникальным GUID'ом для tracking'а, передаваемым в запросе. Не работает из-за вопросов безопасности. C>Попытка номер 3 — разбиваем на два этапа: получение уникального GUID'а первым запросом, а потом использование этого GUID'а во втором.
C>Получается криво.
Здравствуйте, Cyberax, Вы писали: C>Хех. Мне приходили GUID'ы вида 000000000000001, 000000000000002 и т.д.
Не вижу проблемы. Видимо, это оттого, что я не представляю себе вашу задачу. Если бы вы её мне описали, то я бы смог спроектировать для вас RESTful API.
А так мне остаётся только гадать, какую именно проблему с безопасностью вы подразумеваете.
C>Ага, только вот не всегда.
Это проблемы не вас, а клиента.
C>Так мне нужно два объекта обновить "одновременно". REST это делает крайне тяжёлым.
Ещё раз: в REST так не бывает. Классический пример, на котором иллюстрируют транзакции первокурсникам — "перевод денег со счёта". В REST он не делается путём декремента одного счёта и инкремента другого. В REST он делается при помощи записи объекта-транзакции, которая ссылается на оба счёта. Так понятно?
То есть делаем PUT на .../<userAccountID/transactions/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX.xml
Использование GUID гарантирует нам, что мы можем безопасно делать retry, не рискуя перевести деньги дважды. Использование userAccountID гарантирует нам, что транзакции от разных пользователей расположены в разных местах, что позволяет навернуть security и избежать проблемы нечаянного расшаривания кэша.
Ad-hoc транзакций в REST "из коробки" нет. Но их можно придумать, если есть убедительная причина.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Cyberax, Вы писали: C>Агащаз. Как мне найти все параметры, по которым можно искать объект? Или список необходимых параметров при его создании?
Вежливые люди при реализации протокола рендерят XHTML-формы с подсказками.
См. например http://apscatalog.com/all-app/
Видите — всё есть. И как искать, и как сабмиттить. Давайте посмотрим, сможете ли вы сходу найти вопрос, на который не получится ответить путём банального взгляда в браузер.
В более простых случаях REST полагается на WYSIWYG — то есть просто берёте документ, описывающий объект, и делаете PUT такого же документа.
Сам по себе документ может быть насколько угодно self-descriptive. C>А никак, только читать доку. Кстати, если происходит ошибка (скажем, из-за неправильного параметра) — то "you're out of luck". Стандарта на передачу ошибок тоже нет.
Стандарт, конечно же, есть. И он ничуть не хуже, чем SOAP, в котором любимая ошибка — The creator of this fault did not specify a Reason.
Есть коды 4xx и 5xx, плюс возможность отрендерить сколько угодно деталей про ошибку. C>Да ну? Я по WSDL практически всегда могу читать без проблем как работает сервис. C>К примеру, наш родной service2.wsdl — что в нём непонятного?
Ну так он же родной. Попробуйте взять какой-нибудь настоящий сервис. Вот, из последнего, с чем мы имели дело — Office365 API.
Там даже с докой-то не разберёшься.
C>Минимальный объём документации необходим, но не сильно большой.
Ну давайте дадим мне ссылку на минимально интересный WSDL, и посмотрим, далеко ли удастся продвинуться без документации.
C>КАК его изучать?
C>Вот тебе реальная ссылка на пример REST API: C>http://chart.apis.google.com/chart?chs=220x150&cht=lc&chco=224499&chm=B,76A4FB,0,0,0&chxt=x,y&chxs=0,000000,12,0&chd=s:rswx7796&chxl=0:|Nov|Dec|Jan|Feb|Mar|Apr|May|Jun|1:||$4,999,700||$9,999,400||$14,999,100
Простите, а почему вы думаете, что это — REST?
REST — это не просто отказ от WSDL и SOAP. C>Где тут discoverability? http://chart.apis.google.com/chart выдаёт 400. http://code.google.com/apis/chart/ перегоняет на http://code.google.com/apis/chart/ — где ты фиг найдёшь доку, так как этот API у них deprecated.
Вы, похоже, путаете REST c чем-то другим. REST — вот: http://developers.facebook.com/docs/reference/api/, см., в частности, раздел Introspection.
S>>В REST все объекты являются адресуемыми, так что можно передавать URI. C>Неверно. Скажем, я не могу из клиента передать ссылку серверу на мой объект — в мобильном телефоне веб-серверы не работают.
Верно. Вы просто не понимаете, о чём я говорю. C>Не говоря уж о том, что это исключительно хрупкий подход.
Поясняю: В соседнем ответе я привёл пример с банковской транзакцией.
Ну так в отличие от WSDL, где я должен буду передавать в метод Transfer() какие-то непрозрачные идентификаторы счетов, в REST я буду постить что-то типа
Либо, вместо алиасов checking/savings, я буду писать прямо полные номера счетов. Whatever. Ничто не мешает протоколу работать в обоих случаях.
При этом про существование этих URL я могу узнать из того же сервиса, просто побраузив вокруг.
Речи про указание объектов на стороне клиента в REST не идёт.
C>Слова "REST — это подход" вообще гнилая отмаза. Примерно как "я стратег, а не тактик" в анекдоте про зайцев и сову.
Похоже, вы просто не умеете готовить REST и не очень хорошо понимаете, что это такое. Давайте продолжим эту дискуссию — я уверен, это существенно улучшит ваше отношение к REST.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Qbit86, Вы писали:
Q>Нет. Паттерн Стратегия выглядит точно так же (вплоть до UML-диаграммы), как и паттерн Состояние. И тем не менее, это разные паттерны.
Это если рассматривать только статическую часть схемы.
Вообще какой-то глупый упор в этих паттернах GoF на статическую структуру решения. И как следствие — в обсуждениях тоже. Статическая структура — это самый низкий, подчиненный уровень. Более того, ввиду своей подчиненности требуемому функционалу, могут иметь несколько подходящих вариантов исполнения. И наоборот, одно и то же исполнение может решать несколько задач. Зависит от того, какую модель происходящего мы нарисуем себе в голове.
C>>>Добавлю ещё: C>>>6) Отсутствие само-описания типа WSDL для SOAP. S>>как раз с discoverability в REST всё очень хорошо. C>Агащаз. Как мне найти все параметры, по которым можно искать объект? Или список необходимых параметров при его создании?
C>А никак, только читать доку. Кстати, если происходит ошибка (скажем, из-за неправильного параметра) — то "you're out of luck". Стандарта на передачу ошибок тоже нет.