Как стать автором
Обновить

Комментарии 148

Автор хотел сделать провокацию в духе «Node.js is a cancer», но недотянул.
Аргументы в духе
Например, большинство браузеров имеют ограниченную поддержку PUT и DELETE.

RESTful API очень трудно дебажить

Словарь REST недостаточно насыщен

настолько убоги, что даже комментировать нечего.

Не понимаю, зачем переводить какой-то бред. В англоязычном сегменте его уже засмеяли.
Почему сразу бред то? Некоторые аргументы, конечно, высосаны из пальца. Но отсутствие спецификации и полная привязка к транспортному протоколу весьма весомые (для некоторых проектов).
Понимаете, привязка к транспортному протоколу — это особенность REST. Для определенных ситуаций это достоинство, для определенных — недостаток. Окей, да.

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

(скажем, формально SOAP тоже не зависит от транспорта. А теперь скажите мне, сколько раз в своей жизни вы видели SOAP, реализованный не поверх HTTP?)
Типичный заголовок для привлечения внимания, я не говорил что он мне нравится :)

Несколько раз встречал JMS. В общем, привязка к HTTP может быть критической в случаях интеграции с разнородными системами, либо, например, если планируется поддержка WebSockets.
Типичный заголовок для привлечения внимания, я не говорил что он мне нравится :)

Так и аргументация под стать заголовку.

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

Знаете, в случае веб-приложений (и веб-сервисов) я еще ни разу не видел, чтобы интегрируемые системы были гомогенными.
Добро пожаловать в кровавый интерпрайз :)
Угу, «кровавый интерпрайз».

Один российский банк: DB/2 — .net over MS SQL.
Одно российское федеральное ведомство: .net — BizTalk — Lotus — (три разных имплементации SOAP на Java) — 1С.
Поясню про интерпрайз. Я имею в виду не гомогенные системы, а часто изменяющиеся требования и требуемая (тавтология...) гибкость и полиморфность решений.
… и как это говорит за/против REST? Да никак, в общем-то.
Это говорит против использования REST в интерпрайз
Каким образом? REST — очень гибкая парадигма, и, скажем, версионирование ему дается легче, чем SOAP.

Впрочем, в enterprise лучше всего, по моему опыту, работают шины сообщений.
А теперь скажите мне, сколько раз в своей жизни вы видели SOAP, реализованный не поверх HTTP?)
Пока работали над обменом сообщений со смежными системами — каждый день видел.
Если не секрет, какие именно технологии?
IBM WebSphere MQ (кстати, если кто-то будет выбирать MQ — ни в коем случае не выбирайте WebSphere! — там клиент под .NET уродский)
WCF и биндинг или напрямую работа с очередью?
Работали напрямую, пока я не завернул эту радость в WCF :) Правда, биндинг MQ остался недописанным, потому что из-за особенностей разбиения приложения на слои пришлось пересылать полученные из MQ сообщения между слоями через HTTP.

Ходят слухи, что в 2016 году нам выделят еще несколько логических адресов на шине — и тогда про HTTP можно будет забыть.
Почему-то я так и думал…
Как уже заметили ниже: кто-то говорит что REST надо использовать везде? В подавляющем кол-ве проектов «переносить канал связи» не нужно.
Я это и писал
(для некоторых проектов)
Хотите секрет открою? Для некоторых проектов не подходит Javascript. Жду статью от вас «Javascript — большая ложь».
Да вы издеваетесь? Мне НЕ понравился эта статья, мне НЕ нравятся желтые заголовки. Я утверждаю лишь то, что 2 аргумента из статьи «не бред», как написал кто-то выше.
Ок, поясняю:
1) Отсутствие спецификации компенсируется гайдами от разных компаний/людей. Типа как тут недавно от Яндекса.

2) Привязка к транспортному протоколу — это сама суть REST, осознанный шаг. Идея в том, что HTTP очень популярен, поэтому проще привязаться, чем городить абстракции. И вообще он в основном для конечного пользователя, нежели для интеграций.
Зачем методологии спецификация? Это же набор принципов и советов для создания проектов под определенные задачи. А у проекта уже и спецификация будет.
Ну так «Node.js is a cancer» же)
Основная проблема RESTful в том, что каждый раз при создании нового API фактически заново создается транслятор HTTP-to-SQL. Зачастую выходит так, что сам API имеет реляционный характер (/users/1, /users/messages), в коде приложения используется ORM, а потом снова используется реляционная модель. Особенно нелепо это выглядит в приложениях, которые делают только самые примитивные CRUD операции.

Есть, например, проект HTSQL, в котором на базе HTTP строится мощный язык запросов практически со всеми часто используемыми возможностями SQL, который напрямую транслируется в весьма оптимальный запрос на SQL. Для nginx (openresty) есть модуль ngx_drizzle, который умеет асинхронно отправлять запросы в MySQL и модуль rds_json, который в потоковом режиме строит из результатов JSON. Т. е. самое простое API можно создавать прямо в config-ах nginx как-то так:

location ~ /(?<resources>cities|rockets) {
  rds_json on;

  location ~ /(?<id>\d+) {
     postgres_pass   database;
     postgres_query  "SELECT * FROM $resources WHERE id=$id";
  }

  location ~ / {
    postgres_pass   database;
    postgres_query  "SELECT * FROM $resources";
  }
}


Конечно, помимо таких простых запросов часто нужна дополнительная бизнес-логика, но часть задач можно уже сейчас переложить на БД. Например, для небольших проектов на уровне БД можно делать авторизацию с помощью недавно появившегося в PostgreSQL row-level security.

В общем, нужно переосмыслять идею REST, а не плодить одинаковые решения с одинаковыми архитектурными ошибками.
Основная проблема RESTful в том, что каждый раз при создании нового API фактически заново создается транслятор HTTP-to-SQL. Зачастую выходит так, что сам API имеет реляционный характер (/users/1, /users/messages), в коде приложения используется ORM, а потом снова используется реляционная модель. Особенно нелепо это выглядит в приложениях, которые делают только самые примитивные CRUD операции

Ээээ, а OData?
Во-первых, OData хоть и открытый стандарт, все его нормальные серверные реализации написаны под .NET.
Во-вторых, он довольно монструозный и имеет легкий Microsoft-овский налет.
Пример запроса
services.odata.org/v4(S(34wtn2c0hkuk5ekg0pjr513b))/TripPinServiceRW/People('lewisblack')/Trips/$ref HTTP/1.1

И в-третьих, увы, многие попытки стандартизовать что-то в мире REST (и JSON API в частности) провалились.
Ну провалились, и что? Это не отменяет того факта, что подход жизнеспособен. Возможно, ему просто не нужны стандарты в таком количестве?

Ну и да, вам разумно напомнили, что за REST далеко не обязательно стоит реляционная БД, так что ваш пойнт сам по себе не очень валиден.
Насчет ngx_drizzle: Какие молодцы, выстроили свой протокол (если это можно так назввать) поверх HTTP, а сами даже про идемпотентность не слышали (будем инсерты в базу через GET делать, ага).
Это не протокол поверх HTTP, почитайте повнимательнее. Это просто модуль, делающий запросы к MySQL (или Drizzle, для которого он изначально писался) асинхронно и выдающий данные в формате RDS, которые следующим модулем по цепочке (например, rds_json или rds_csv) уже непосредственно преобразуются в ответ. Этот модуль написан человеком из CloudFlare и вполне себе production-ready. Читать данные из POST-запроса можно, например, с помощь модуля form-input-nginx. Есть еще большой список того, что нужно для идеального полноценного API, но база для этого уже готова.
P.S.
Зачастую выходит так, что сам API имеет реляционный характер (/users/1, /users/messages), в коде приложения используется ORM, а потом снова используется реляционная модель.

Почитайте про CQRS, что-ли.
В приведенной вами цитате я не настаиваю на какой-то конкретной парадигме, а всего лишь константирую факт и привожу примеры. С приципом CQRS я знаком и понимаю, что не так может быть с API, представленном в виде исключительно CRUD-операций.
P.S., небольшая опечатка, имел ввиду /users/1/messages
Основная проблема RESTful в том, что каждый раз при создании нового API фактически заново создается транслятор HTTP-to-SQL. Зачастую выходит так, что сам API имеет реляционный характер (/users/1, /users/messages), в коде приложения используется ORM, а потом снова используется реляционная модель. Особенно нелепо это выглядит в приложениях, которые делают только самые примитивные CRUD операции.

А в чем проблема? Скажем в Java сериализация/десериализация json в java объекты делается буквально одной строчкой, причем никто не мешает добавить этим java объектам теги JPA и сразу напрямую сохранять их в ORM. Зачем тут придумывать трансляторы SQL? И не вижу у SOUP и других технологий каких-то преимуществ при сохранении через ORM.
Вопрос не в том, насколько легко это делается и тем более, не в том, на какой платформе. Вопрос в том, насколько много лишних действий происходит под этой кучей красивых оберток. В предложенном вами варианте вообще безумная цепочка: автоматическая десериализация JSON в POJO, потом автоматическая сериализация из POJO в подстроку SQL-запроса и наконец автоматическое построение SQL-запроса. Я первоначально хотел обратить внимание, что с учетом проблем object-to-relational городить relational-to-object-to-relational для простых задач просто абсурдно.
Предложите другие варианты, проблема в том что когда пытаются сделать попроще, вроде простой генерации SQL запросов руками, потом получают проблемы c sql injection. Да, в любом самом простом решении все равно используется десятки оберток, обертки для работы с сокетами, обертки для работы с базой данных и т.д.
Есть, например, проект HTSQL, в котором на базе HTTP строится мощный язык запросов практически со всеми часто используемыми возможностями SQL, который напрямую транслируется в весьма оптимальный запрос на SQL. Для nginx (openresty) есть модуль ngx_drizzle, который умеет асинхронно отправлять запросы в MySQL и модуль rds_json, который в потоковом режиме строит из результатов JSON. Т. е. самое простое API можно создавать прямо в config-ах nginx как-то так:

Эээ, то есть вы считаете куча оберток проекта HTSQL чем-то лучше? Обертка на HTTP, обертка на JSON, обертка в виде своего языка запросов, обертка над SQL, причем все обертки свои кастомные да ещё все в одном проекте (явное нарушения принципа одной обязанности). Уж, лучше взять какое-нибудь nosql хранилище, вроде mongoDb и сохранять json из Rest'a прямо напрямую в монгу.
Я упомянул HTSQL как отличную концепцию, а не как конкретную реализацию. Правильно было бы, на мой взгляд, сделать парсер путя с параметрами в URI в самой БД как отдельный модуль и для ряда запросов вообще обходить парсер SQL, просто поставив БД в upstream на кеширующий сервер. Это не всегда хорошее и не всегда универсальное решение, но практика показывает, что SQL нередко бывает bottleneck-ом. Если что, я сейчас потихоньку пишу такой модуль для MySQL, работая напрямую с InnoDB и со многими потенциальными проблемами знаком.
Честно говоря не понял этой отличной концепции HTSQL, ни один разумный человек на даст делать прямые SQL запросы любому пользователю прямо в браузере, потому что это просто мечта хакера. Если вы готовы дать кому-то возможность делать прямые SQL запросы в вашу базу данных, так дайте ему удаленный доступ и возможность делать нормальные SQL запросы, зачем тут «посредник» со своим языком запросов?

Если что, я сейчас потихоньку пишу такой модуль для MySQL, работая напрямую с InnoDB и со многими потенциальными проблемами знаком.

Какой модуль-то? Сделать из SQL базы данных noSQL? А зачем? Честных noSQL баз данных существует огромное количество от key-value хранилищ до сохранения полноценных документов, а SQL база данных всегда будет хуже эмулировать noSQL.

Правильно было бы, на мой взгляд, сделать парсер путя с параметрами в URI в самой БД

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

Нет.

Я не говорил о том, что запросы должны идти без какой-либо авторизации.

SQL база данных всегда будет хуже эмулировать noSQL.

Нет.

ACID.

Модуль memcached к MySQL видели?

Просто посмотрите примеры и предстаьте себе нативную реализацию прямо в БД. Это не NoSQL в обычном понимании. Все тоже самое что с SQL, только другой язык запросов, который можно передавать в БД как есть, без лишних промежуточных представлений и строить на его основе execution plan.

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

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

Не так важно авторизация или нет, возможность динамически задавать SQL запросы всегда небезопасна и её стоит разрешать либо собственным сотрудникам, либо очень хорошо проверенным клиентам. Скажем, вы возвращаете select * from users where user_id = 87333, где id это тот самый пользователь, а он берет и меняет запрос select * from users where user_id = 1 и получает все данные администратора. Да, есть способы ограничить права в SQL базах, но не всегда они работают по отдельным записям и всегда можно ошибиться и дать прав больше чем нужно.

Именно поэтому прямой доступ к своему SQL серверу ни одна нормальная компания клиентам не даст, для того и придумали Rest и т.п. технологии. А вы по сути предлагаете давать прямой доступ из-за чего такая технология ограничена внутренней сетью компании и ничем не лучше просто удаленного доступа к базе данных.
А где вы видите relation-to-object?
REST во многих его реализациях — это как раз и есть попытка сделать HTTP реляционным, я написал об этом в первом комментарии.
1) Никогда таких попыток не встречал, можете привести пример? Вообще-то, json это как раз объект, например это родной объект для javascript, а по правилу не хранения состояния Rest'a ссылки на другой json вообще-то не очень корректны, откуда тут реляционность-то?
2) Те кто пытается сделать Rest реляционным — сами себе злобные буратины,
3) В любом случае json это объект (даже если он какую-то реляционность эмулирует), поэтому json в ORM, это преобразования объекта в объект,
Практически в любом API, где имеется какая-то связность между объектами («сообщения пользователя», «комментарии к новости»), выстраиваются отношения один-к-одному и один-ко-многим. Пример — GitHub API, да и практически любой другой API в стиле Sinatra. Ссылки между объектами — это не хранение состояния. Под хранением состояния, например, подразумевается привязка результатов и контекста выполения к текущей сессии. От этого отказываются, поскольку при масштабировании проще всего, удобнее и надежнее создавать одинаковые ноды и не задумываться о переносе контекста. JSON — это не объект, это синтаксическая конструкция, описывающая объект, причем далеко не самым лаконичным способом. И если вы не понимаете, например, что именно происходит при сериализации/десериализации JSON в POJO, не понимаете смысл идеи RESTful, и, наконец, не понимаете, что я хотел донести, не нужно, пожалуйста, заводить спор.
Это не реляционность, это сохранение id другой сущности, реляционность появится только при загрузки в реляционную базу данных. Сам по себе id другой сущности не может создать ссылку, нужно либо отправить объект на которой ссылка в одном json'е, либо поднимать его из реляционной базы данных. Так что в json'е как в любом объекте может быть только «эмуляция» ссылочности не более того.

какая-то связность между объектами

Она есть конечно, но не уровне Rest'a и json'a, для json'a все равно текстовое поле или поле хранящее id другой сущности, связность исключительно на уровне бизнес модели.

И если вы не понимаете, например, что именно происходит при сериализации/десериализации JSON в POJO

В Javascript например ничего не происходит, JSON это и есть объект которые может содержать даже методы javascript'a.

JSON — это не объект, это синтаксическая конструкция, описывающая объект, причем далеко не самым лаконичным способом.

JSON в javascript это объект, которые может содержать даже методы javascript'a
В Javascript например ничего не происходит

А вот и нет, происходит. Только на этапе трансляции, а не интерпретации. А при десериализации в Plain Old Java Object либо дергается небыстрый Reflection API, либо на лету осуществляется кодогенирация, что не лучше. Нравится блуждать в мире абстракций — пожалуйста. Вот тут, например, люди запускают три интерпретатора JS (JavaScriptCore, JavaScriptCore и V8) и шлют данные между ними alert-ом через pipe в этом самом JSON и ничего, 1500 звезд на GitHub-е.
Вы знаете разницу между Java и JavaScript'ом? Какой Reflection API?

дергается небыстрый Reflection API, либо на лету осуществляется кодогенирация

либо программисты используют не DOM парсер, если так важна скорость
Вы знаете разницу между Java и JavaScript'ом? Какой Reflection API?

А в чем проблема? Скажем в Java сериализация/десериализация json в java объекты делается буквально одной строчкой, причем никто не мешает добавить этим java объектам теги JPA и сразу напрямую сохранять их в ORM.


А вот DOM здесь вообще при чем?
Вы не знаете что парсеры не ограничиваются DOM (или Data Binding) моделью? В том же jackson'e есть аж три вида парсера, если вопрос в памяти и производительности, то нормальный программист использует Streaming парсеры.
И повторяю вопрос какая связь между Java и JavaScript'ом, в последнем ответе я говорил только о JavaScript'e?
Я вас только что процитировал, вы первоначально писали про де-/сериализацию JSON в Java. А вот о Document Object Model вообще ни слова не было и к сериализации данных ни в Java, ни в JavaScript-е это не имеет никакого отношения.

Что значит — какая связь?
Если что, пример с PhantomJS был просто как наглядная демонстрация безумного нагромождения абстракций, сопоставимого с вашим «одной строчкой на Java».
Ладно, если ваша аргументация уже скатилась до намеков, что, мол, я не понимаю разницы между Java и JavaScript, пора поставить точку.

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

Ну а насчет вас я для себя уже все выяснил.
Тью, а какое это отношение это имеет к проф.деятельности? Я мог бы понять если бы вы мое CV откопали и рассказывали что у вас-то в сто раз больше опыта. Действительно, смысла такого дискуссии с переходом на личности явно нет, тем более что вы не отвечаете ни на один неудобный вам вопрос.
Практически в любом API, где имеется какая-то связность между объектами («сообщения пользователя», «комментарии к новости»), выстраиваются отношения один-к-одному и один-ко-многим.

Это если вы мыслите отношениями.

При моделировании этого домена вполне можно решить, что комментарии к новости (я просто не знаю, что вы понимаете под сообщениями пользователя) — это часть агрегата (здравствуй, DDD) «новость», и это классическое отношение композиции (которое классическими РСУБД адекватно не моделируется).
Что вы вкладываете в понятие «реляционным» во фразе «сделать HTTP реляционным», и в каких реализациях REST вы это видели?
Я тщетно пытаюсь донести мысль, что URL в REST теряет свое первоначальное значение становится и не идентификатором, а языком запросов, в чем-то подобным SQL (работающим в рамках реляционной модели), а значит, пора уменьшать прослойку кода. Особенно это актуально для single-page-applications, которые большую часть данных тянут на лету с сервера в том виде, в котором они представлены в базе данных и не стремятся выбраться за границы CRUD.

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

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

Пример скинул выше

Какой именно? GitHub?
Бизнес-логика в триггерах — это похлеще пресловутого define true false…
В триггерах — да, но кое-какие вещи сделать как view можно себе позволить.
Как же меня раздражают подобные жёлтые заголовки для статей.
Я читал эту статью пару недель назад и даже там до последнего думал что автор шутит ) Но нет — всё серъёзно.
Я тоже не люблю такие провокационные заголовки, но статья называлась так в оригинале.
К моему счастью, бэк-енд команда согласилась параллельно с RESTful запустить JSON-pure API, просто перенеся все свои методы и коды в JSON. Спустя несколько месяцев все мои знакомые, ранее использовавшие RESTful, перешли на JSON-pure, осознав, что это гораздо удобнее.

Одну ногу я побрила…
А второй нет — я ее уже давно отстрелила.
Поздравляю автора — он изобрёл SOAP, только на основе JSON, а не XML. Всё то же самое — отвязка от транспортного протокола и перенос всей логики в сам протокол.

На самом деле все эти ужасы преувеличены. Браузеры спокойно поддерживают метод DELETE (мы из приложения на Angular.js спокойно шлём запросы DELETE и PATCH пачками) и не очень стандартные коды ответов (мы так же широко используем 422 Unprocessable Entity, чтобы показать, что запрос был семантически некорректным и транзакция произведена не была и надо смотреть в тело ответа — там будут сообщения об ошибках).
Браузеры то да, а вот серверное нестандартное не факт.
Если смотреть стандартный случай, клиент + api, то обычно все ок, но на практике часто бывают взаимные взаимодействия с различными сервисами, а везде реализовывать RESTful задолбаешься.
Они их поддерживают только в JS, в html — нет
А как вы себе представляете работу с REST API из HTML? Они в общем-то и не для этого придуманы.
Как по мне, самый большой недостаток REST — высокие затраты времени на разработку. Если API предоставляется через SOAP (так поступает большинство крупных компаний банковского, страхового и других B2B секторов), достаточно взять кодогенератор, который из WSDL файла сгенерирует прокси классы и всё, через 3 минуты ты можешь делать запросы, при этом особенности транспорта тебя не волнуют. Круче всего это реализовал Microsoft в своём WCF, где через конфигурационный файл можно выбрать любой транспорт, от http(s) до MSMQ (включая tcp и named pipes). WSDL файл и SOAP автоматически генерируются на основе кода.

А REST, вот я так в толк и не возьму, какие у него основные плюсы. Меньше данных передаётся? В мире единицы сайтов, для которых экономия на траффике в таких масштабах превысит стоимость разработки REST.
Всё структурно? Да хз, как бы да, но реально дебажить приходится смотря на все 7 мест, указанных в статье. И опять же, если следовать RESTful, то те моменты, которые через RPC решаются за один запрос, через RESTful за кучу. Не понимаю я его смысл как «эталона», короче.
Если API предоставляется через SOAP (так поступает большинство крупных компаний банковского, страхового и других B2B секторов), достаточно взять кодогенератор, который из WSDL файла сгенерирует прокси классы и всё, через 3 минуты ты можешь делать запросы, при этом особенности транспорта тебя не волнуют. Круче всего это реализовал Microsoft в своём WCF, где через конфигурационный файл можно выбрать любой транспорт, от http(s) до MSMQ (включая tcp и named pipes). WSDL файл и SOAP автоматически генерируются на основе кода.

… а потом ты внезапно выясняешь две вещи.

(а) реализации SOAP на этой и той стороне отличаются (например, вы по-разному трактуете время без указания часового пояса)
(б) в WSDL (точнее, XSD) описаны далеко не все детали формата, а в паре мест стоит xs:any.
(ц) авторизация… авторизация? авторизация, мать ее!

Real life stories.

В мире единицы сайтов, для которых экономия на траффике в таких масштабах превысит стоимость разработки REST.

А что такого в «стоимости разработки REST»? Чем она радикально выше, чем разработка под SOAP?

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

Конкретный пример можно?

А REST, вот я так в толк и не возьму, какие у него основные плюсы.

(а) простота использования из браузерного кода
(б) опора на существующую HTTP-инфраструктуру (например, кэширование)
(ц) «встроенная» мультиформатность
(д) более очевидная семантика
(а) реализации SOAP на этой и той стороне отличаются (например, вы по-разному трактуете время без указания часового пояса)
(б) в WSDL (точнее, XSD) описаны далеко не все детали формата, а в паре мест стоит xs:any.

Если API кривой, то не важно REST он, не REST, проблемы всё равно будут.
(ц) авторизация… авторизация? авторизация, мать ее!
не понял вас тут

А что такого в «стоимости разработки REST»? Чем она радикально выше, чем разработка под SOAP?

Ну, как минимум, надо свой транспорт писать. Формирование JSON, запрос к удалённому компьютеру, считывание ошибок, протоколирование, парсинг JSON обратно в объекты. В реализации SOAP майкрософта это всё идёт из коробки, вызвал функцию на сгенерированном прокси-классе, обратно получил результат, случилась ошибка — вывалился exception. Это работает прозрачно, как будто всё происходит в рамках одного процесса.

Конкретный пример можно?

Конкретный пример — работа с транзакциями, описание разницы есть тут: habrahabr.ru/post/131343

(а) простота использования из браузерного кода
(б) опора на существующую HTTP-инфраструктуру (например, кэширование)
(ц) «встроенная» мультиформатность
(д) более очевидная семантика

Тут согласен, но это делает его в основном пригодным только для фронтэнда. Причём в рамках одного домена, из-за ограничения на кроссдоменные запросы.
Если API кривой, то не важно REST он, не REST, проблемы всё равно будут.

Конечно, просто в этом месте понимаешь, что — внезапно — SOAP не решает. А иногда, что хуже, мешает, потому что формировать его руками тяжело и сложно.

не понял вас тут

В HTTP есть простые и понятные способы аутентификации и авторизации. В SOAP с этим все весело, особенно когда вы делаете межвендорную (например, .net — Java) интеграцию.

Ну, как минимум, надо свой транспорт писать

Http-клиент, в любой разумной платформе из коробки.

Формирование JSON, запрос к удалённому компьютеру, считывание ошибок, протоколирование, парсинг JSON обратно в объекты.

У того же Microsoft для всего этого давно есть обертка (HttpRequestMessage/HttpResponseMessage) с расширениями.

Это работает прозрачно, как будто всё происходит в рамках одного процесса.

До первой проблемы, особенно проблемы формата 400 Bad Request без объяснений.

Конкретный пример — работа с транзакциями

Если под транзакциями вы понимаете ACID, то в RPC с этим все тоже плохо. А если под транзакцией вы понимаете бизнес-операцию, которая предполагает много внутренней логики, то в REST они прекрасно делаются.

Тут согласен, но это делает его в основном пригодным только для фронтэнда

Угу, а теперь давайте задумаемся, что мы не хотим писать два разных сервиса для веб-клиентов и мобильных клиентов, а после этого добавим сюда third-party. Вот, собственно, и вся интеграция для нормального веб-приложения.

Причём в рамках одного домена, из-за ограничения на кроссдоменные запросы.

CORS.
Ну конечно SOAP не решает, разве я это где-то говорил?

В HTTP есть простые и понятные способы аутентификации и авторизации. В SOAP с этим все весело, особенно когда вы делаете межвендорную (например, .net — Java) интеграцию.

На практике, обычно выделяют отдельный метод для авторизации, который возвращает токен и этот токен используется в последующих запросах, это не является проблемой.
Http-клиент, в любой разумной платформе из коробки.
У того же Microsoft для всего этого давно есть обертка (HttpRequestMessage/HttpResponseMessage) с расширениями.


Клиент то из коробки, но это не отменяет необходимость формирования JSON, запроса к удалённому компьютеру, считывания ошибок, протоколирования, парсинга JSON обратно в объекты. А клиент да, позволяет делать запрос не беспокоясь о TCP и нижележащих протоколах.

До первой проблемы, особенно проблемы формата 400 Bad Request без объяснений.

А REST тут чем лучше? Если тот же Bad Request без объяснений вываливается? Это вопрос качества реализации API, если она кривая, придётся мучиться.

Под транзакциями я понимаю ACID и не понимаю что там плохого.

Угу, а теперь давайте задумаемся, что мы не хотим писать два разных сервиса для веб-клиентов и мобильных клиентов, а после этого добавим сюда third-party. Вот, собственно, и вся интеграция для нормального веб-приложения.

Для B2C возможно, у B2B таких проблем обычно не стоит.

Вам не кажется, что мы с вами о разных вещах говорим? Моя позиция: REST переоценен, во многих ситуациях SOAP позволяет экономить время на разработке клиента, а в ряде случаев и сервиса. Вы с этим принципиально не согласны?
Ну конечно SOAP не решает, разве я это где-то говорил?

Вот здесь:

Если API предоставляется через SOAP [...], достаточно взять кодогенератор, который из WSDL файла сгенерирует прокси классы и всё, через 3 минуты ты можешь делать запросы, при этом особенности транспорта тебя не волнуют.


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

Стандарты? WS-Security? Нет, не слышал. Вот в этом и проблема: каждый делает по-своему.

это не отменяет необходимость формирования JSON, запроса к удалённому компьютеру, считывания ошибок, протоколирования, парсинга JSON обратно в объекты.

Вы, видимо, не в курсе:

//GET
var response = await client.GetAsync("api/products/1");
response.EnsureSuccessStatusCode();
Product product = await response.Content.ReadAsAsync>Product>();

//POST
var gizmo = new Product() { Name = "Gizmo", Price = 100, Category = "Widget" };
await client.PostAsJsonAsync("api/products", gizmo);


А REST тут чем лучше?

Тем, что между вами и происходящим меньше уровней абстракции, проще понять, что происходит.

Под транзакциями я понимаю ACID и не понимаю что там плохого.

Распределенные транзакции плохо удаются любому протоколу, не важно, RPC это или SOAP. Это проблема распределенности, а не протокола.

Моя позиция: REST переоценен, во многих ситуациях SOAP позволяет экономить время на разработке клиента, а в ряде случаев и сервиса. Вы с этим принципиально не согласны?

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

Что важнее, эта «экономия» — она по сравнению с самописным обменом. Если же вы будете сравнивать с любой другой устоявшейся парадигмой (messaging, REST), то выяснится, что различия более архитектурные, чем временные, и именно от архитектуры и надо плясать.
Распределенные транзакции плохо удаются любому протоколу, не важно, RPC это или SOAP.

Прошу прощения, читать «RPC или REST».
Вот здесь:

Если API предоставляется через SOAP [...], достаточно взять кодогенератор, который из WSDL файла сгенерирует прокси классы и всё, через 3 минуты ты можешь делать запросы, при этом особенности транспорта тебя не волнуют.

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

Стандарты? WS-Security? Нет, не слышал. Вот в этом и проблема: каждый делает по-своему.

А в REST значит всё стандартизировано? Ну-ну.

Вы, видимо, не в курсе

А у вас класс Product откуда взялся? Сами написали? Ну круто. Хорошо если там 3 поля, а как начинаешь работать со страховыми продуктами, то там мама не горюй какой объём и вложенность. Помнится, интегрировали мы одну страховую, расчёт туристического страхования (не самый сложный продукт), объём сгенерированного кода был за 3 000 строк. Сколько по КАСКО (сложный продукт) я даже думать не хочу. Для аналогичного продукта другой страховой компании, написанного как раз на REST, было затрачено около 70 человекочасов дополнительно на транспорт.

Распределенные транзакции плохо удаются любому протоколу, не важно, RPC это или SOAP. Это проблема распределенности, а не протокола.

Обоснуйте

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

А SOAP и RPC — не архитектура? И что такое временные различия?
В этом абзаце написано про то, что SOAP позволяет автоматически сгенерировать прокси классы, которые позволят сразу делать запросы не учитывая конкретных особенностей транспорта. Где вы тут увидели что SOAP решает?

В утверждении «позволят сразу делать запросы». В реальности это далеко не всегда так.

А в REST значит всё стандартизировано?

В REST не стандартизовано, но в REST безопасность делегирована на транспортный уровень, а там, в свою очередь, есть устоявшиеся практики. Разница в том, что в SOAP в половине случаев безопасность определяется сгенеренными прокси, а они могут уметь, а могут и нет. В качестве развлечения предлагаю вам добавить в WCF подписание сообщений по ГОСТу.

А у вас класс Product откуда взялся? Сами написали? Ну круто

Конечно, нет. Тут есть два занятных нюанса.

Во-первых, REST не означает JSON. А как только мы берем в качестве формата xml, нам сразу доступен весь инструментарий от xsd.

Во-вторых, для JSON тоже есть схемы и генераторы.

Обоснуйте

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

А SOAP и RPC — не архитектура?

SOAP и RPC (как и messaging или REST) — это парадигмы, между которыми есть крупные отличия, радикально влияющие на архитектуру решения.

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

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

В реальности это далеко не всегда так.

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

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

А что мешает использовать https для SOAP запросов? Что до практик, вы сами упоминали WS-Security. То что им не всегда следуют — не проблема SOAP, а кривизны рук разработчиков API. Это как машина, знаете, правила нарушает не она, а водитель.

В качестве развлечения предлагаю вам добавить в WCF подписание сообщений по ГОСТу.

Делал я подписание сообщений и ручную проверку сертификатов. Не по ГОСТу, а по AES, но с учётом того, что инфраструктура криптопровайдеров стандартизирована, а ГОСТовские провайдеры есть, не думаю что там будут особые сложности.
А в REST, кстати, это как-то очень просто делается? Там вроде только свелосипедить можно, https ГОСТ не особо уважает, насколько я знаю.

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

И что, есть реализации координаторов для REST?

SOAP и RPC (как и messaging или REST) — это парадигмы, между которыми есть крупные отличия, радикально влияющие на архитектуру решения.

Ну REST как бы больше ограничений накладывает. Тут и отсутствие состояний, и обязательное использование http, и жёстка завязка на предопределённые коды ответа и методы http. SOAP (simple object access protocol) и RPC (remote procedure call) по определению с этой стороны гораздо более гибкие.
Но если API спроектирован хорошо, все прокси-классы сгенерируются и запросы можно будет делать сразу. Но это не проблема SOAP, а кривых рук разработчиков API.

К сожалению, SOAP API чаще спроектирован плохо, чем хорошо. И частично это как раз следствие внутренней избыточности SOAP, а частично — разницы реализаций на разных сторонах.

А что мешает использовать https для SOAP запросов?

Не знаю, что мешает. Но регулярно не используют.

То что им не всегда следуют — не проблема SOAP, а кривизны рук разработчиков API.

… или неумения конкретного инструмента.

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

Не по ГОСТу, а по AES, но с учётом того, что инфраструктура криптопровайдеров стандартизирована, а ГОСТовские провайдеры есть, не думаю что там будут особые сложности.

К сожалению, в .net она стандартизирована только до определенного предела, а дальше начинаются проблемы. Так что сложности и веселье там есть в полный рост (начиная с того, кстати, что WCF генерит некорректные с точки зрения XMLDSIG атрибуты).

А в REST, кстати, это как-то очень просто делается?

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

И что, есть реализации координаторов для REST?

А что, есть реализации координаторов для SOAP?

Ну REST как бы больше ограничений накладывает. Тут и отсутствие состояний, и обязательное использование http, и жёстка завязка на предопределённые коды ответа и методы http. SOAP (simple object access protocol) и RPC (remote procedure call) по определению в с этой стороны гораздо более гибкие.

Вы считаете, что в SOAP нет ограничений? Даже если мы берем самую базовую реализацию — вам нужно контролировать actions и структуру сообщения. В реальности почти всегда вам нужно больше — как минимум, безопасность — и дальше вы немедленно влетаете в то, как именно и какую вам надо делать. А еще, на «чистом честном» SOAP тяжело делать версионирование с одновременной поддержкой нескольких версий. Не невозможно, но тяжело.

И это только с одной стороны. А с другой стороны: вы считаете, что ограничения — это зло? А я так не считаю, я считаю, что они позволяют более строго формализовать архитектуру и уменьшить количество неопределенностей.

Вы почему-то считаете, что я считаю, что SOAP плохой, а REST — хороший. А я считаю, что каждый из них подходит для своей задачи, а для каких-то задач подходит что-то третье.
Вы же почему-то предложили не WS-Security, а «На практике, обычно выделяют отдельный метод для авторизации, который возвращает токен и этот токен используется в последующих запросах».

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

А что, есть реализации координаторов для SOAP?

Ну как бы да: msdn.microsoft.com/en-us/library/ff384250.aspx

Вы почему-то считаете, что я считаю, что SOAP плохой, а REST — хороший. А я считаю, что каждый из них подходит для своей задачи, а для каких-то задач подходит что-то третье.

Я так считаю? Вы же начали отвечать на мой комментарий, пытаясь прицепиться к каждому пункту.
Не я предложил, это чаще всего встречается в существующих API, которые мы к себе интегрируема.

Вот вам и демонстрация «правильного дизайна API».

Ну как бы да: msdn.microsoft.com/en-us/library/ff384250.aspx

Это пока еще не SOAP, а WCF. С кем совместима эта реализация (насколько я понимаю, там WS-AT)?
это не отменяет необходимость формирования JSON, запроса к удалённому компьютеру, считывания ошибок, протоколирования, парсинга JSON обратно в объекты.

Зачем? Для таких вещей есть библиотеки, скажем в Java есть RestEasy для создания rest сервиса/клиента парой строчек и Gson/Jackson для сериализации JSON в Java объекты одной строчкой. В целом, сделать Rest сервис с нуля можно за несколько часов (включая доменную модель, простую бизнес обработку и теги сохранение данных в JPA), сделать аналогичный WSDL вряд ли получится быстрее.

А у вас класс Product откуда взялся? Сами написали? Ну круто.

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

Если API предоставляется через SOAP [...], достаточно взять кодогенератор, который из WSDL файла сгенерирует прокси классы и всё, через 3 минуты ты можешь делать запросы, при этом особенности транспорта тебя не волнуют.

Так WSDL тоже кто-то должен сначала сделать. Когда вы пишите клиента к чужому SOUP вам WSDL дадут, а если надо написать самим все с нуля? К тому же далеко не всегда автогенерация из WSDL во всех ЯП работает сразу и без проблем.

объём сгенерированного кода был за 3 000 строк.

А это много? Скажем в Java если я сделаю за 15 минут класс с сотней полей, а потом скажу IDEA сгенерить сетеры, гетеры, конструкторы, toString, hashcode, equals, javadoc'ки — у меня легко получится класс на 3 тыс. строк.
Основной плюс REST в том, что любой программист может взять свой любимый язык программирования и за пару часов написать на нем клиента к любому REST-сервису. В случае с RPC, если генератор прокси-классов для любимого языка кривой, то придется либо пилить напильником, либо использовать нелюбимый язык. У меня так было со Thrift 3 года назад. В Java он работал как часы, а в Python — баг на баге. Может быть сейчас и пофиксили, но желания использовать его с тех пор нету.
Ну это же проблема не RPC, а конкретной реализации кодогенератора.
Нет, это как раз-таки проблема RPC, что без кодогенератора — никуда. Как принимается решение о том, что использовать? Например, на упомянутом мной проекте было так: бэкэнд — Java, фронтенд — Python. Вопрос: что используем для связки? Java-команда предлагает Thrift: «Вот, смотрите, он быстрый, есть binary-протокол и в документации написано, что Python поддерживается». Ок, соглашаемся. Пишем спецификации, генерируем код. Код — говно, но вроде работает. А потом проект начинает расти и начинаются первые баги. Выясняется, что binary протокол не умет работать с Unicode. Что некоторые классы почему-то не генерируются. И если посчитать сколько времени было убито на поиск багов, на допиливание генератора. А потом перевести это в деньги. А потом показать счет клиенту… Ну вы поняли.

Я не то чтобы против RPC. Просто у каждой технологии своя область применения. RPC хорош для внутреннего использования, где вы точно знаете на каких ЯП будут писаться клиенты, и что для них существует нормальный кодогенератор. REST же хорош для публичного API, тогда можно ограничиться хорошей документацией, по которой любой желающий сможет написать своего клиента на любом, даже самом экзотичном ЯП.
Разработка и синхронизация с кодом на scala/java/c# файлов WDSL требует времени и сил. И специальных инструментов — синтаксис ужасен, лично я в vim я такое редактировать не способен.

Отладка RESTful-подобных интерфейсов как раз удобна, используя curl или powershell Invoke-RestMethod из командной строки.
Не уверен, что использовать vim для разработки на C# хорошая идея, есть специализированные инструменты, типа студии (которая бесплатная в community edition), в которой таких проблем нет.
WSDL файл и SOAP автоматически генерируются на основе кода.

… и на свет появляется очередное го*но-API, состоящее из точащих наружу кишков го*но-приложения.

Извините за резкость, но API — это то, над чем надо очень, очень хорошо думать. И то, что в REST нельзя добавить 100500 разношестных методов на все случаи жизни с кучей побочных эффектов — это очень хорошо для публичных API.
Да можно, можно в REST добавить кучу «методов», было бы желание. Всегда есть POST на произвольный адрес или с произвольным контентом (который REST не противоречит, хотя и предпочтительно его избегать).

Так что применение головы все же обязательно.
В REST нет кучи методов, а есть ресурсы. Не определились с ресурсами — начали гордить кучу костылей с произвольными адресами и произвольным контентом.
Потому и кавычки.

Речь о том, что если не понимать методологию, то можно наплодить кривой API где угодно.
JSON-RPC 2.0? Там еще и batch запросы можно делать.
автор противопоставляет создание REST-запросов — через формирование урлов с параметрами и request-тела, а также разбор http-кодов и response-тела — простому JSON со всеми запросами, параметрами и кодами в удобоваримом виде одним текстом. в данном контексте с тем же успехом можно заменить JSON на XML. и вариант с JSON/XML выглядит более органичным и расширяемым.
и те, кто считает, что автор «тупит», не формируют ведь REST-запросы ручками, а используют всякие либки и фреймворки.
но если бы вам пришлось их формировать — без сторонних либок REST или SOAP — вы бы стали морочиться с полным HTTP-REST или простым HTTP-GET/POST и JSON/XML? другое дело, кто хочет писать велосипеды…
для JSON-pure тоже наверняка есть либки и фрейворки. косяк автора в том, что он их не разбирает на плюсы и минусы, а просто говорит, что RESTful — гамно. за что и закидался тухлыми яйцами.
много дыма из ничего.
но если бы вам пришлось их формировать — без сторонних либок REST или SOAP — вы бы стали морочиться с полным HTTP-REST или простым HTTP-GET/POST и JSON/XML?

Конечно, стали бы. Намного проще отправить пустой запрос DELETE uri, чем формировать тело сообщения с командой и идентификатором.
Жду перевода статьи «JSONpure API — большая ложь», где главным аргументом против будет указана нетипизированность данных и хорошо если будет в качестве решения какой-нибудь edn, ато ведь и к XML вернемся, как расширяемой и самоописываемой обертке.
Отлично, теперь я знаю как называется то что я использую.
У меня была похожая реакция)
Проблема RESTful в том что мало кто делает именно точно RESTful, почти у всех какие-то особенности и оговорки.
Да и он далеко не все проблемы решает связанные с взаимодествие с API.

А еще вот есть Apache Thrift кстати, который решает больше проблем, немного в другой плоскости, но тоже по теме.

Нет, я не спорю, Рой — отличный парень и, конечно же, у него было множество классных идей… Тем не менее, я не уверен, что RESTful API попадает в их список.

Выглядит как замаскированный личный наезд, что не очень приятно. RESTful все же показался многим полезной вещью для создания разного рода публичных и частных API без какого-либо сильного вендора за спиной, так что нельзя сказать что это «ложь» или что автор публикации сплоховал и придумал какую-фигню.
RESP был прекрасен по сравнению с подходами вроде SOAP своей stateless философией, и именно популяризацию такой философии я считаю основной заслугой REST'a. С другой стороны, использование протокола НТТР для описания семантики приложения — это ужасный рак, прокрустово ложе, в которое мы себя добровольно загоняем. Весь этот сыр-бор — из-за классической ошибки, называемой «смешение уровней абстракции», которая произошла с протоколом НТТР. этот прокотол описывает взаимодействие между узлом сети и ресурсом. Но разработчики НТТР решили также включить в набор статусов терминологию, которая относится к бизнес-логике конкретного приложения, и залезли таким образом на уровень выше, куда лезть не следовало. Я имею ввиду как статусы вроде Payment Required, так и более завуалированную ересь вроде Created(зачем такой ответ? Если запрос явно предполагал создание чего-либо, то достаточно ответа ОК, то есть, «все получилось»). Резюмируя, я бы сказал, что рест является удачным и еффективным подходом, построенным на ошибочной концепции.
Какой из этого выход? Таки использовать JSON-pure АРІ и иметь возможность точно описать всю специфическую для приложения логику, не только Payment Required, а и, скажем, Upgrade Account required, или Admin rights required, и что заблагорассудится.
Извиняюсь, но почему вы противопоставляете SOAP и stateless? Много веб-сервисов именно stateless и являются, более того — именно такие сервисы и рекомендуется делать.
Потому что rest — stateless, а soap — нет. Мне больше нравится stateless подход, и то, что rest его использует, я считаю большим плюсом rest'а.
Много веб-сервисов именно stateless и являются, более того — именно такие сервисы и рекомендуется делать.

Да, полностью согласен, а к чему вы повторили общеизвестный факт?
Потому что rest — stateless, а soap — нет.
С чего бы? SOAP over HTTP — ничуть не менее stateless, чем REST.
это популярное заблуждение, почитайте:
http://www.ibm.com/developerworks/library/ws-spmyths/
over HTTP или нет, значения не имеет.
REST же stateless по своему определению.

Все, что написано там, применимо и к REST тоже. Разница лишь в том, что в REST за такое будут бить по рукам, а при использовании SOAP — нет.

Но если вам нравится stateless подход — ничто не мешает использовать его совместно с SOAP.
Скажем так, в REST'е отсутствие состояния — краеугольный камень, и если это требование нарушено, возникает вопрос, а рест ли это, или рест-подобная поделка, которых сейчас очень много? В соапе использование состояния во многих случаях неизбежно и его отсутствие — это скорее исключение.
Это в каких же случаях состояние в соапе неизбежно?

(я надеюсь, мы говорим про техническое состояние, а не бизнес)
По-моему, никто и не запрещает отвечать OK. Мне кажется коды ответа не конкретную ошибку отдают, а класс ошибоки, более подробную информацию и инструкции по дальнейшим действиям надо в теле ответа смотреть (а тем, кто пишет API, выводить их, а не скрывать).
Для того что бы решить проблемы упомянутые в статье — нужно использовать гипермедиа типы (hateoas).
Но там такой сыр-бор твориться…

* У Swagger'a, в этой роли, пока что ничего не получается, и поддержка довольно ужасна.
НЛО прилетело и опубликовало эту надпись здесь
Теперь мнение невежд высказанное в письменной форме называется троллинг? :)
НЛО прилетело и опубликовало эту надпись здесь
Такой срач стоит вокруг совершенно пустой статьи.

Достаточно заметить, что автор попросту не знает, что такое REST.

REST — это стиль архитектуры программного обеспечения для построения распределенных масштабируемых веб-сервисов. Рой выступал за использование стандартных HTTP методов так, чтобы придавать запросам определённый смысл. [...] Многие положительно отнеслись к такой парадигме и стали использовать её в разработке веб-сервисов с использованием HTTP. Это и есть то, что мы называем RESTful API.


Да нет же! Использование стандартной номенклатуры методов и статусов — только часть REST, не самая важная (вообще-то можно строить REST-сервисы и не поверх HTTP). Важных ограничений четыре:

— клиент-серверная архитектура (в частности, клиента не заботит, на каких технологиях реализован сервер за счет унифицированного протокола)

— отсутствие состояний: все детали операции содержатся в самой операции; т.е. в парадигме REST нельзя сделать вот так:
DELETE /user/data
со взятием id юзера из куки. REST-клиент обязан отправить запрос вида
DELETE /user/{userid}/data
А куку использовать строго для проверки, имеет ли право этот юзер удалять данные {userid}

— управление кэшированием — методы, статусы и заголовки позволяют гибко кэшировать максимальный объём данных; в частности
GET /user/data — невозможно закэшировать, потому что id юзера знает только сервер
GET /user/{userid}/data — кэшировать уже можно

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

Ну и многочисленные фактические ошибки по ходу статьи не позволяют рассматривать её сколько-нибудь всерьёз

Например, когда мы должны использовать код 200 ОК? Можем ли мы использовать его для подтверждения успешного апдейта записи, или нам стоит использовать код 201 Created?


RFC2616: If an existing resource is modified, either the 200 (OK) or 204 (No Content) response codes SHOULD be sent to indicate successful completion of the request.

На самом деле, единственными кодами, обработки которых можно не бояться, являются 200 ОК и 500 Internal server error.


Здесь я сломался и дальше не читал.
Да троллинг это, причем весьма толстый
>>Достаточно заметить, что автор попросту не знает, что такое REST.
Простите, но вы тоже фигню всякую пишите :)

>>— клиент-серверная архитектура (в частности, клиента не заботит, на каких технологиях >>реализован сервер за счет унифицированного протокола)
Если взять тупо чистый http запрос, клиенту не пофигу что на сервре?

>>— отсутствие состояний: все детали операции содержатся в самой операции; т.е. в парадигме
>>REST нельзя сделать вот так:
>>DELETE /user/data
>>со взятием id юзера из куки. REST-клиент обязан отправить запрос вида
>>DELETE /user/{userid}/data

А кука у вас в чем так в этом случае принципиально от урла отличается? Так же на сервер уйдет в общем случае в заголовке.

>>А куку использовать строго для проверки, имеет ли право этот юзер удалять данные {userid}
Так вы перепутали куки с серверной сессией? Ну так в по идеалогии Restful нельзя сохранять состояние.

>>— управление кэшированием — методы, статусы и заголовки позволяют гибко кэшировать >>максимальный объём данных; в частности
>>GET /user/data — невозможно закэшировать, потому что id юзера знает только сервер
>>GET /user/{userid}/data — кэшировать уже можно

И только сервер знает, когда протухнет кеш, вообщем со стороны управлением кеша без разницы.

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

Ну я хотя бы множественное лицо второго рода настоящего времени глаголов отличаю от повелительного наклонения.
Писать — глагол первого спряжения, в окончаниях настоящего времени пишется «е».

> Если взять тупо чистый http запрос, клиенту не пофигу что на сервре?

Если у вас организована передача данных в виде, например, сериализованных PHP-объектов, то клиенту приходится знать, что на сервере работает PHP. REST-методология требует представлять операции в виде собственно HTTP-запросов так, чтобы семантика операции была понятна из самого запроса.

> А кука у вас в чем так в этом случае принципиально от урла отличается? Так же на сервер уйдет в общем случае в заголовке.

Тем, что URL не указывает конкретный ресурс, над которым выполняется операция. В семантике HTTP операция DELETE /user/data означает удаление всех данных всех юзеров.

> Ну так в по идеалогии Restful нельзя сохранять состояние.

Я именно это и написал.

> И только сервер знает, когда протухнет кеш, вообщем со стороны управлением кеша без разницы.

Интересное «без разницы».
GET /user/{userid} клиент может кэшировать по отдельность для каждого userid, и инвалидировать кэш также по отдельности (используя If-Modified-Since, например). GET /user кэшировать вообще нельзя.

> Очень много чего можно так проксировать, не уведомляя клиент, странный довод.

Нет, не очень.
Если у вас есть операция
GET /?method=шарах
И сервер проксирует её до другого гейтвея, она вполне может оказаться где-то по пути закэшированной и в реальности не выполниться. Эта схема может работать если и только если все промежуточные узлы понимают и правильно интерпретируют семантику HTTP.
> множественное лицо второго рода настоящего времени

Тьфу, множественное число второго лица, конечно же.
>Ну я хотя бы множественное лицо второго рода
>настоящего времени глаголов отличаю от повелительного наклонения.
>Писать — глагол первого спряжения, в окончаниях настоящего времени пишется «е».

Чтож, подловили :) Хотя мы тут про Rest вроде?

>Если у вас организована передача данных в виде, например, сериализованных
>PHP-объектов, то клиенту приходится знать, что на сервере работает PHP.
Какие-то вы бредовые примеры приводите, я писал про сравнение Restfull и обычный просто http, но впрочем даже в таком бредовом примере, нет клиенту не надо знать что там PHP, надо только знать формат сериализации, а он строгий.

>REST-методология требует представлять операции в виде собственно
> HTTP-запросов так, чтобы семантика операции была понятна из самого запроса.
Каша какая-то. Как связана семантика операции и формат получаемых данных?

>> Ну так в по идеалогии Restful нельзя сохранять состояние.
>Я именно это и написал
Тогда причем тут куки вообще?

>Интересное «без разницы».
>GET /user/{userid} клиент может кэшировать по отдельность для каждого userid, и
> инвалидировать кэш также по отдельности (используя If-Modified-Since, например).
>GET /user кэшировать вообще нельзя.
В вашем первом странном примере без разницы.

>Нет, не очень.
>Если у вас есть операция
>GET /?method=шарах
>И сервер проксирует её до другого гейтвея,
>она вполне может оказаться где-то по пути закэшированной
>и в реальности не выполниться.
Ну и? Есть метод и он что-то получает, раз GET, вы позволили ему где-то закешироваться.

>Эта схема может работать если и только если все промежуточные
>узлы понимают и правильно интерпретируют семантику HTTP.
Так Rest то тут вообще причем?
Абсолютно ни при чём, вы совершенно правы.
— отсутствие состояний: все детали операции содержатся в самой операции; т.е. в парадигме REST нельзя сделать вот так:
DELETE /user/data

Можно, если у вас есть ресурс по адресу test.ru/user/data, url — всего лишь идентификатор ресурса, REST не навязывает никаких правил по именованию и иерархии.
Ну не знаю, мне после мамонтообразного SOAP и такого-же JSON-RPC REST кажется наиболее лаконичным методом реализации API. По поводу дебага, например на Django можно отлично писать Unit-тесты, если вы пользуетесь rest_framework. Извините заранее, все комментарии не читал. Статья, имхо, вброс и скрытый пиар.
Удивлен что никто не написал про ограничения метода GET, в случаях каких-нибудь query-запросов частенько помещаются не все параметры и приходится, опять же, использовать POST.
Я согласен с автором статьи. Думаю самый хороший вариант с точки зрения разработчика — это уяснить суть RESTful сервисов, понять какие бывают типы запросов, какие из них реально поддерживаются, разобраться в кодах, в целом «подружиться» с каналом передачи протоколом HTTP и т.п. Все это даст понимание технологии и знания как правильно с ней работать. Дальше действительно удобней использовать только POST и с помощью JSON уже формировать удобную для себя структуру пакета сообщений, реализовывая по сути старый добрый request/response подход, который зарекомендовал себя давно и использовался почти во всех системах и технология сетевого взаимодействия. Надо заметить при этом, что в своих сообщениях разработчик может поддерживать принципы REST, введя свои типы сообщений для CRUD операций и поддерживая логику их обработки. HTTP в данном случае будет просто транспортом. Отвязка от канала передачи — это (опятьже согласен с автором) большой плюс.
Надо заметить при этом, что в своих сообщениях разработчик может поддерживать принципы REST, введя свои типы сообщений для CRUD операций и поддерживая логику их обработки.

Не может. Использовать POST для чтения данных — противоестественно для REST.
А если при получении данных у нас ацкая куча фильтров и в GET мы не влезаем? :)
Значит, у вас техническая проблема, для решения которой вам придется положить на семантику. Беда и печаль.
Это не проблема, а необходимость :)
И их может быть много разных, поэтому по факту Restful это лишь набор рекомендаций, которые далеко не во всех случаях вообще реально использовать.
Не спорю. Но если вы их не используете — то у вас уже не REST (по крайней мере, в контексте данной операции/ресурса).
Ну в том то и прикол, я вот например не видел ни одного большого проекта, где реально REST, а не «ну почти REST». И все споры где что и как должно быть по канонам — они бессмысленны и выдают возможный недостаток опыта :)
Почему же. Споры «как должно быть по канонам» имеют смысл, чтобы понимать, куда стремиться — и чтобы, если можно сделать правильно, делать правильно.
>Споры «как должно быть по канонам» имеют смысл, чтобы понимать, куда стремиться
Зачем спорить о том, что четко описано?

>если можно сделать правильно, делать правильно.
Правильно это понятие относительное, в абсолютном понимании правильно решенная задача — это задача выполняющая некие изначальные условия. Для того чтобы понять, что есть restful спорить смысла нет, достаточно почитать.
Зачем спорить о том, что четко описано? [...] Для того чтобы понять, что есть restful спорить смысла нет, достаточно почитать.

Как видно из дискуссий — описано недостаточно четко, чтобы все понимали.
Верно. Это противоестественно для REST. Но речь как раз и идет о том, чтобы не сковывать себя ограничениями REST отвязать свою модель зваимодействия поверх HTTP. POST запрос в плане ограничений самый беспроблемный и имеет массу преимуществ с точки зрения программиста. Использовать его как транспорт для любых типов запросов — удобно. Семантику запроса в этом случае убираем в тело передаваемых JSON данных и используем POST паровоз для отправки наших запросов и получения ответов от сервера.

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

>Но речь как раз и идет о том, чтобы не сковывать себя ограничениями REST отвязать
>свою модель зваимодействия поверх HTTP. POST запрос в плане ограничений
>самый беспроблемный и имеет массу преимуществ с точки зрения программиста.

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

>Принципы REST если они вам удобны и дороги — можно перенести и
>внутрь ваших сообщений, поджерживая все составляющие REST запроса

А это еще хуже, когда REST называют то, что им не является и путают людей.
Нельзя «перенести принципы REST внутрь сообщений», об этом и речь. Получите вы обычный RPC, коим много лет уже.
Верно. Но я не вижу проблемы в RPC. Давно зарекоммендовавший себя концепт.
Не видите — и хорошо, ваше личное дело, может у вас и нет проблем. Только REST-ом не называйте.
Дао Вебсервиса. (Или да хватит же изобретать велосипеды!) — http://habrahabr.ru/post/75248/
Угу. Уже сильно больше одного раза обсудили все проблемы SOAP, надо еще раз повторить?
Да нет. Я к тому, что глупо гнаться за понятием, когда занимаешься практической работой. Не вижу смысла навешивать ярлыки на технологии, принимать одну их них за священную корову и потом мучаться от ее недостатков в ежедневной работе. Это удел молодых программистов, которые пороху еще не нанюхались и собак съели мало :)
И хватит минусовать — это как-то глупо что ли. Моя точка зрения имеет такое же а то и большее право на существование по сравнению с вашей :)
Архитектура (в том числе хорошая), поддерживаемость, тестируемость — это все «понятия». За ними тоже не надо гнаться?

Никто не считает REST священной коровой. Это конкретный подход с весьма конкретными ограничениями. Кому ограничения не нравятся — окей, пожалуйста, сколько угодно, можете не использовать, можете даже ругать и говорить, что другая технология лучше; но зачем называть то, что вы используете вместо REST — REST?
Да, тоже не надо гнаться. Любая идея, возведенная в абсолют — зло :) Архитектура — это выбранный способ устройства частей приложения и их взаимодействия. Может быть любой. Какой бы она ни была — это будет архитектура. Плохая она или хорошая — можно судить используя выбранные критерии. Поддерживаемость, тестируемость и прочие так нахываемые "-ilities" как раз и являются этими самыми криетриями. Подчеркну еще раз, что оценку архитектуры на «хорошесть» делают именно относительно выбранных криетериев, а не всех имеющихся в природе в принципе. Это важный момент. Выбор тех или или иных критериев обусловлен требованиями к приложению. Которые (обычно) обусловлены бизнес задачами (в случае коммерческого ПО по крайней мере).

Думаю мне удалось донести мысль о том, что стремление соответствовать какому-либо понятию, не имея обусловленной понятными причинами потребности в этом, а просто потому что так «правильно» — это глупость?

На счет самих слов «использовать REST» — не понимаю, зачем вы мне приписываете неясные формулировки, а потом возмущаетесь что я там что-то не так навал и асамозабвенно минусуете мои коментарии. Я четко сказал, что можно заимствовать концепцию («Принципы REST») и избавиться от многих ограничений данного подхода. Ну а что как называть — дело вкуса :) Тут следуется договориться о терминах перед тем как спорить.

REST — это не конкретная технология (реализация), а стиль архитектуры что ли… метод взаимодействия частей распределённого приложения в сети интернет.

При соблюдении (надо сказать довольно расплывчатых требований) та или иная реализвация вашего сервиса может быть с той или иной долей справедливости названа «RESTful» веб сервисом.
Да, тоже не надо гнаться. Любая идея, возведенная в абсолют

Вы почему-то приравниваете «гнаться за идеей» к «возведено в абсолют». А зря.

Я четко сказал, что можно заимствовать концепцию («Принципы REST») и избавиться от многих ограничений данного подхода.

Конкретно описанный вами подход (ввести свои типы сообщений, поместить семантику внутрь них, использовать только POST) противоречит противоречит концепции REST (например, пункту про кэшируемость). Поэтому я не понимаю, что вы собираетесь «заимствовать».
Кешируемость в ряде случаев — как раз относится к минусам, откоторых хочется избавиться.

Заимствовать (не дублировать полностью) основной концепт этого подхода и cделать удобную — обладающую необходимыми свойствами и характеристиками (в рамках выбранных критериев) — реализацию API. Я говорю об этом. И о том, что «RESTful webservices» напрасно возвели на пьедестал и холиворно бездумно стараются его придерживаться всегда и везде. Любая концепция хороша к месту.

Утомился я пререкаться. Думаю, продолжать не уже буду. Спасибо за дискуссию.
Кешируемость в ряде случаев — как раз относится к минусам, откоторых хочется избавиться.

Ага, а вы избавляетесь везде, и что-то говорите о возведении в абсолют.

Заимствовать (не дублировать полностью) основной концепт этого подхода

Мне вот, все-таки, очень интересно, что же вы считаете «основным концептом» REST.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации