От переводчика:
Я впервые попробовал перевести статью такого объёма и IT-тематики, с радостью прочту ваши комментарии и замечания. Что же касается самой статьи: я не согласен с автором как минимум потому, что, по сути, он заменяет REST на… REST (!!!), но немного в другом обрамлении. Однако, не смотря на то, что в статье преподносится много очевидных вещей, мне она показалась достойной обсуждения на Хабре.

Почему Вам стоит похоронить эту популярную технологию

image

RESTful api — это чудесно, ведь так?


Если за последние 10 лет Вы читали резюме веб-разработчиков, то Вам простительно думать, что RESTful API — это некое божественное дарование, сошедшее к нам с небес. REST API используется повсюду, даже маркетологи постоянно упоминают о нём в материалах, предназначенных сугубо для руководства или персонала.

Так на сколько всё же хороша идея REST API? Перед тем как мы разберемся с этим вопросом, давайте посмотрим откуда растут корни…

Откуда вообще взялся REST?


Данная технология стала популярной, когда она была подробно описана и представлена Роем Филдингом в его докторской диссертации под названием Architectural Styles and the Design of Network-based Software Architectures в 2000 году. Рой известен своими вкладами в развитие веба, в особенности HTTP.

Так что же такое RESTful API?


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

Таким образом, данные HTTP-запросы будут иметь различный смысловую нагрузку в REST:
  • GET /object/list
  • POST /object/list
  • PUT /object/list

Выше только некоторые виды запросов, а вот весь их список: CONNECT, DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT, TRACE. Если вы даже не слышали о некоторых из них — не беда, так как есть методы, которые практически никогда не поддерживаются ни клиентским, ни серверным приложением.

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

image

Итак, одна транзакция по такому API будет состоять, как минимум, из следующего:
  • Метод запроса, например, GET
  • Путь запроса, например, /object/list
  • Тело запроса, например, форма
  • Код ответа, например, 200 ОК
  • Тело ответа, например, данные в формате JSON

Многие положительно отнеслись к такой парадигме и стали использовать её в разработке веб-сервисов с использованием HTTP. Это и есть то, что мы называем RESTful API.

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

На самом деле RESTful API довольно ужасно


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

Вскоре мы посмотрим на другое, более правильное решение для построения API, но, перед тем как сделать это, нам следует понять 5 главных проблем RESTful API, которые делают его дорогим, уязвимым к ошибкам и неудобным. Начнём!

Проблема №1: До сих пор нет общего согласования того, что такое RESTful API


Вряд ли кто-то задумывался над тем почему эта технология называется именно «RESTful», а не «RESTpure»? (прим. переводчика: pure — чёткий, понятный) А потому что никто не может определиться с тем, что из себя представляют все методы запроса, коды ответа, тела и т.д.

Например, когда мы должны использовать код 200 ОК? Можем ли мы использовать его для подтверждения успешного апдейта записи, или нам стоит использовать код 201 Created? Судя по всему, нужно использовать код 250 Updated, однако его не существует. И еще, кто-нибудь может объяснить что означает код 417 Expectation failed?! Кто-нибудь кроме Роя, конечно.

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

Если бы это было единственной проблемой, то я, наверное, смирился бы и продолжал писать RESTful API по сей день. Однако, наш список только раскрывается…

Проблема №2: Словарь REST поддерживается не полностью


Даже если бы мы решили первую проблему, то столкнулись бы со следующей, практической: большинство клиентских и серверных приложений поддерживают не все коды ответа и, собственно, глаголы, означающие HTTP-методы. Например, большинство браузеров имеют ограниченную поддержку PUT и DELETE.

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

  • Метод HTTP запроса, например, POST
  • Адрес запроса, например, /object/list
  • Метод, который мы на самом деле подразумеваем, например, DELETE
  • Тело запроса, например, данные из формы

Ситуация с кодами ответа не лучше. Разные браузеры (и серверные приложения тоже) часто понимают эти коды по-разному. Например, получив код 307 Temporary redirect, один браузер может позволить пользовательскому скрипту рассмотреть этот ответ и отменить действие до его выполнения. Другой браузер может просто напросто запретить скрипту делать что-либо. На самом деле, единственными кодами, обработки которых можно не бояться, являются 200 ОК и 500 Internal server error. В остальных же случаях поддержка ответов варьируется от «довольно хорошей» до «просто ужасной». Именно по-этому нам часто приходится дополнять тело ответа кодом, который мы на самом деле подразумевали.

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

Проблема №3: Словарь REST недостаточно насыщен


Словарь, состоящий только из HTTP методов и кодов ответа, является слишком ограниченным для эффективной передачи и приёма разнообразной информации, необходимой всем приложениям. Представьте, что мы создали приложение, из которого мы хотим отправить клиенту ответ «render complete». К сожалению, мы не можем сделать это с помощью HTTP кодов, так как, во-первых, такого кода не существует, а во-вторых мы не можем его создать, так как HTTP — не расширяемый. Минутка разочарования. Думаю нам снова придётся вставлять то, что мы подразумеваем в тело ответа.

Также проблема в том, что у нас не один словарь, у нас их три! Коды ответов — это числовые значения (200, 201, 500), которые отличаются от представления методов запроса (GET, POST, PUT и т.д.), а тело ответа и вовсе в формате JSON. Выполнение REST транзакций — это как отправка письма на английском языке в Китай и получение оттуда ответа морзянкой. Все эти сложности являются крупным источником путаницы и ошибок. Вот мы и перешли к следующей глобальной проблеме: дебаггинг.

Проблема №4: RESTful API очень трудно дебажить


Если Вы когда-то работали с REST API, то Вы наверняка в курсе, что его почти невозможно дебажить. Для того, чтобы понять то, что происходит во время транзакции, нам приходится просматривать сразу 7 мест:

  • Метод HTTP запроса, например, POST
  • Адрес запроса, например, /object/list
  • Метод, который мы на самом деле подразумеваем (в теле запроса), например, DELETE
  • Собственно, тело запроса, например, данные из формы
  • Код ответа, например, 200 ОК
  • Код, который мы подразумевали (в теле ответа), например, 206 Partial Content
  • Собственно, тело ответа

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

Проблема №5: Как правило, RESTful API привязаны к протоколу HTTP


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

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

К счастью, есть хорошее решение, которое позволяет избежать либо минимизировать все проблемы RESTful API. Встречайте!

Шаг вперёд: JSON-pure API


JSON-pure API справляется с большинством проблем, которые мы только что рассмотрели.

  • Использует только один метод для передачи данных — обычно POST для HTTP и SEND в случае использования Web Sockets
  • Механизм передачи и содержимое запроса полностью независимы. Все ошибки, предупреждения и данные передаются в теле запроса, в формате JSON
  • Используется лишь один код ответа, чтобы подтвердить успешную передачу, обычно это 200 ОК
  • Механизм передачи и содержимое ответа полностью независимы. Все ошибки, предупреждения и данные передаются в теле ответа, в формате JSON
  • Гораздо проще дебажить, ведь все данные находятся в одном месте в легко-читаемом формате JSON
  • Легко перенести на любой канал связи, например, HTTP/S, WebSockets, XMPP, telnet, SFTP, SCP, or SSH

JSON-pure API появилось в следствии осознания разработчиками того факта, что RESTful API не особо дружелюбно к браузерам и самим разработчикам. Разделение сообщения и способа передачи делает JSON-pure API быстрым, надежным, простым в использовании, портировании и поиске ошибок. Сегодня, если нам понадобится, например, использовать API Твиттера, то мазохисты выберут RESTful API. Остальные же обратятся к JSON-pure API, или, как его еще называют, «Web API».

За последние десять лет меня не раз просили использовать RESTful вместо JSON-pure. Крайний раз, когда мне чуть было не пришлось поддерживать RESTful API, был в 2011 году. К моему счастью, бэк-енд команда согласилась параллельно с RESTful запустить JSON-pure API, просто перенеся все свои методы и коды в JSON.
Спустя несколько месяцев все мои знакомые, ранее использовавшие RESTful, перешли на JSON-pure, осознав, что это гораздо удобнее.

Оригинал статьи: mmikowski.github.io/
Автор: Michael S. Mikowski

Комментарии (147)


  1. Ununtrium
    01.09.2015 10:45
    +27

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

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

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

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

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

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


    1. Encircled
      01.09.2015 10:59
      +22

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


      1. lair
        01.09.2015 11:32
        +12

        Понимаете, привязка к транспортному протоколу — это особенность REST. Для определенных ситуаций это достоинство, для определенных — недостаток. Окей, да.

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

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


        1. Encircled
          01.09.2015 11:40

          Типичный заголовок для привлечения внимания, я не говорил что он мне нравится :)

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


          1. lair
            01.09.2015 11:42

            Типичный заголовок для привлечения внимания, я не говорил что он мне нравится :)

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

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

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


            1. Encircled
              01.09.2015 11:44

              Добро пожаловать в кровавый интерпрайз :)


              1. lair
                01.09.2015 11:48
                +1

                Угу, «кровавый интерпрайз».

                Один российский банк: DB/2 — .net over MS SQL.
                Одно российское федеральное ведомство: .net — BizTalk — Lotus — (три разных имплементации SOAP на Java) — 1С.


                1. Encircled
                  01.09.2015 15:26

                  Поясню про интерпрайз. Я имею в виду не гомогенные системы, а часто изменяющиеся требования и требуемая (тавтология...) гибкость и полиморфность решений.


                  1. lair
                    01.09.2015 15:31
                    +1

                    … и как это говорит за/против REST? Да никак, в общем-то.


                    1. Encircled
                      01.09.2015 15:42
                      -2

                      Это говорит против использования REST в интерпрайз


                      1. lair
                        01.09.2015 15:53
                        +5

                        Каким образом? REST — очень гибкая парадигма, и, скажем, версионирование ему дается легче, чем SOAP.

                        Впрочем, в enterprise лучше всего, по моему опыту, работают шины сообщений.


        1. mayorovp
          01.09.2015 16:10

          А теперь скажите мне, сколько раз в своей жизни вы видели SOAP, реализованный не поверх HTTP?)
          Пока работали над обменом сообщений со смежными системами — каждый день видел.


          1. lair
            01.09.2015 16:10

            Если не секрет, какие именно технологии?


            1. mayorovp
              01.09.2015 16:16

              IBM WebSphere MQ (кстати, если кто-то будет выбирать MQ — ни в коем случае не выбирайте WebSphere! — там клиент под .NET уродский)


              1. lair
                01.09.2015 16:26

                WCF и биндинг или напрямую работа с очередью?


                1. mayorovp
                  01.09.2015 16:39
                  +1

                  Работали напрямую, пока я не завернул эту радость в WCF :) Правда, биндинг MQ остался недописанным, потому что из-за особенностей разбиения приложения на слои пришлось пересылать полученные из MQ сообщения между слоями через HTTP.

                  Ходят слухи, что в 2016 году нам выделят еще несколько логических адресов на шине — и тогда про HTTP можно будет забыть.


                  1. lair
                    01.09.2015 16:54

                    Почему-то я так и думал…


      1. Ununtrium
        01.09.2015 12:32

        Как уже заметили ниже: кто-то говорит что REST надо использовать везде? В подавляющем кол-ве проектов «переносить канал связи» не нужно.


        1. Encircled
          01.09.2015 13:08
          +1

          Я это и писал

          (для некоторых проектов)


          1. Ununtrium
            01.09.2015 14:58
            +1

            Хотите секрет открою? Для некоторых проектов не подходит Javascript. Жду статью от вас «Javascript — большая ложь».


            1. Encircled
              01.09.2015 15:03
              +2

              Да вы издеваетесь? Мне НЕ понравился эта статья, мне НЕ нравятся желтые заголовки. Я утверждаю лишь то, что 2 аргумента из статьи «не бред», как написал кто-то выше.


              1. Ununtrium
                01.09.2015 16:36
                +1

                Ок, поясняю:
                1) Отсутствие спецификации компенсируется гайдами от разных компаний/людей. Типа как тут недавно от Яндекса.

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


                1. Chikiro
                  02.09.2015 23:39

                  Зачем методологии спецификация? Это же набор принципов и советов для создания проектов под определенные задачи. А у проекта уже и спецификация будет.


            1. KReal
              01.09.2015 15:13

              Ну так «Node.js is a cancer» же)


      1. arvitaly
        01.09.2015 18:36

        -


    1. dannote
      01.09.2015 15:43
      +7

      Основная проблема 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, а не плодить одинаковые решения с одинаковыми архитектурными ошибками.


      1. lair
        01.09.2015 15:54

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

        Ээээ, а OData?


        1. dannote
          01.09.2015 19:11
          +2

          Во-первых, OData хоть и открытый стандарт, все его нормальные серверные реализации написаны под .NET.
          Во-вторых, он довольно монструозный и имеет легкий Microsoft-овский налет.

          Пример запроса
          services.odata.org/v4(S(34wtn2c0hkuk5ekg0pjr513b))/TripPinServiceRW/People('lewisblack')/Trips/$ref HTTP/1.1


          1. lair
            01.09.2015 20:22
            +3

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

            Ну и да, вам разумно напомнили, что за REST далеко не обязательно стоит реляционная БД, так что ваш пойнт сам по себе не очень валиден.


      1. Ununtrium
        01.09.2015 16:56

        Насчет ngx_drizzle: Какие молодцы, выстроили свой протокол (если это можно так назввать) поверх HTTP, а сами даже про идемпотентность не слышали (будем инсерты в базу через GET делать, ага).


        1. dannote
          01.09.2015 18:57

          Это не протокол поверх HTTP, почитайте повнимательнее. Это просто модуль, делающий запросы к MySQL (или Drizzle, для которого он изначально писался) асинхронно и выдающий данные в формате RDS, которые следующим модулем по цепочке (например, rds_json или rds_csv) уже непосредственно преобразуются в ответ. Этот модуль написан человеком из CloudFlare и вполне себе production-ready. Читать данные из POST-запроса можно, например, с помощь модуля form-input-nginx. Есть еще большой список того, что нужно для идеального полноценного API, но база для этого уже готова.


      1. Ununtrium
        01.09.2015 17:03
        +1

        P.S.

        Зачастую выходит так, что сам API имеет реляционный характер (/users/1, /users/messages), в коде приложения используется ORM, а потом снова используется реляционная модель.

        Почитайте про CQRS, что-ли.


        1. dannote
          01.09.2015 19:25
          -1

          В приведенной вами цитате я не настаиваю на какой-то конкретной парадигме, а всего лишь константирую факт и привожу примеры. С приципом CQRS я знаком и понимаю, что не так может быть с API, представленном в виде исключительно CRUD-операций.


          1. dannote
            01.09.2015 19:42
            -1

            P.S., небольшая опечатка, имел ввиду /users/1/messages


      1. vedenin1980
        01.09.2015 21:55
        -1

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

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


        1. dannote
          02.09.2015 16:01
          -1

          Вопрос не в том, насколько легко это делается и тем более, не в том, на какой платформе. Вопрос в том, насколько много лишних действий происходит под этой кучей красивых оберток. В предложенном вами варианте вообще безумная цепочка: автоматическая десериализация JSON в POJO, потом автоматическая сериализация из POJO в подстроку SQL-запроса и наконец автоматическое построение SQL-запроса. Я первоначально хотел обратить внимание, что с учетом проблем object-to-relational городить relational-to-object-to-relational для простых задач просто абсурдно.


          1. vedenin1980
            02.09.2015 16:30

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


            1. vedenin1980
              02.09.2015 16:43
              -1

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

              Эээ, то есть вы считаете куча оберток проекта HTSQL чем-то лучше? Обертка на HTTP, обертка на JSON, обертка в виде своего языка запросов, обертка над SQL, причем все обертки свои кастомные да ещё все в одном проекте (явное нарушения принципа одной обязанности). Уж, лучше взять какое-нибудь nosql хранилище, вроде mongoDb и сохранять json из Rest'a прямо напрямую в монгу.


              1. dannote
                03.09.2015 04:32
                -1

                Я упомянул HTSQL как отличную концепцию, а не как конкретную реализацию. Правильно было бы, на мой взгляд, сделать парсер путя с параметрами в URI в самой БД как отдельный модуль и для ряда запросов вообще обходить парсер SQL, просто поставив БД в upstream на кеширующий сервер. Это не всегда хорошее и не всегда универсальное решение, но практика показывает, что SQL нередко бывает bottleneck-ом. Если что, я сейчас потихоньку пишу такой модуль для MySQL, работая напрямую с InnoDB и со многими потенциальными проблемами знаком.


                1. vedenin1980
                  03.09.2015 08:53

                  Честно говоря не понял этой отличной концепции HTSQL, ни один разумный человек на даст делать прямые SQL запросы любому пользователю прямо в браузере, потому что это просто мечта хакера. Если вы готовы дать кому-то возможность делать прямые SQL запросы в вашу базу данных, так дайте ему удаленный доступ и возможность делать нормальные SQL запросы, зачем тут «посредник» со своим языком запросов?

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

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

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

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


                  1. dannote
                    03.09.2015 10:00
                    -1

                    Если вы готовы дать кому-то возможность делать прямые SQL запросы в вашу базу данных,

                    Нет.

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

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

                    Нет.

                    ACID.

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

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

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

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


                    1. vedenin1980
                      03.09.2015 10:16

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

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

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


          1. lair
            02.09.2015 17:05

            А где вы видите relation-to-object?


            1. dannote
              03.09.2015 04:16
              -1

              REST во многих его реализациях — это как раз и есть попытка сделать HTTP реляционным, я написал об этом в первом комментарии.


              1. vedenin1980
                03.09.2015 08:39
                -1

                1) Никогда таких попыток не встречал, можете привести пример? Вообще-то, json это как раз объект, например это родной объект для javascript, а по правилу не хранения состояния Rest'a ссылки на другой json вообще-то не очень корректны, откуда тут реляционность-то?
                2) Те кто пытается сделать Rest реляционным — сами себе злобные буратины,
                3) В любом случае json это объект (даже если он какую-то реляционность эмулирует), поэтому json в ORM, это преобразования объекта в объект,


                1. dannote
                  03.09.2015 09:11
                  -1

                  Практически в любом API, где имеется какая-то связность между объектами («сообщения пользователя», «комментарии к новости»), выстраиваются отношения один-к-одному и один-ко-многим. Пример — GitHub API, да и практически любой другой API в стиле Sinatra. Ссылки между объектами — это не хранение состояния. Под хранением состояния, например, подразумевается привязка результатов и контекста выполения к текущей сессии. От этого отказываются, поскольку при масштабировании проще всего, удобнее и надежнее создавать одинаковые ноды и не задумываться о переносе контекста. JSON — это не объект, это синтаксическая конструкция, описывающая объект, причем далеко не самым лаконичным способом. И если вы не понимаете, например, что именно происходит при сериализации/десериализации JSON в POJO, не понимаете смысл идеи RESTful, и, наконец, не понимаете, что я хотел донести, не нужно, пожалуйста, заводить спор.


                  1. vedenin1980
                    03.09.2015 09:38
                    -1

                    Это не реляционность, это сохранение id другой сущности, реляционность появится только при загрузки в реляционную базу данных. Сам по себе id другой сущности не может создать ссылку, нужно либо отправить объект на которой ссылка в одном json'е, либо поднимать его из реляционной базы данных. Так что в json'е как в любом объекте может быть только «эмуляция» ссылочности не более того.

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

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

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

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

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

                    JSON в javascript это объект, которые может содержать даже методы javascript'a


                    1. dannote
                      03.09.2015 10:26
                      -1

                      В Javascript например ничего не происходит

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


                      1. vedenin1980
                        03.09.2015 10:28
                        -1

                        Вы знаете разницу между Java и JavaScript'ом? Какой Reflection API?

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

                        либо программисты используют не DOM парсер, если так важна скорость


                        1. dannote
                          03.09.2015 10:40
                          -1

                          Вы знаете разницу между Java и JavaScript'ом? Какой Reflection API?

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


                          А вот DOM здесь вообще при чем?


                          1. vedenin1980
                            03.09.2015 10:51
                            -1

                            Вы не знаете что парсеры не ограничиваются DOM (или Data Binding) моделью? В том же jackson'e есть аж три вида парсера, если вопрос в памяти и производительности, то нормальный программист использует Streaming парсеры.
                            И повторяю вопрос какая связь между Java и JavaScript'ом, в последнем ответе я говорил только о JavaScript'e?


                            1. dannote
                              03.09.2015 10:58
                              -1

                              Я вас только что процитировал, вы первоначально писали про де-/сериализацию JSON в Java. А вот о Document Object Model вообще ни слова не было и к сериализации данных ни в Java, ни в JavaScript-е это не имеет никакого отношения.

                              Что значит — какая связь?


                            1. dannote
                              03.09.2015 11:02
                              -1

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


                            1. dannote
                              03.09.2015 11:19
                              -1

                              Ладно, если ваша аргументация уже скатилась до намеков, что, мол, я не понимаю разницы между Java и JavaScript, пора поставить точку.

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

                              Ну а насчет вас я для себя уже все выяснил.


                              1. vedenin1980
                                03.09.2015 11:48

                                Тью, а какое это отношение это имеет к проф.деятельности? Я мог бы понять если бы вы мое CV откопали и рассказывали что у вас-то в сто раз больше опыта. Действительно, смысла такого дискуссии с переходом на личности явно нет, тем более что вы не отвечаете ни на один неудобный вам вопрос.


                  1. lair
                    03.09.2015 11:56

                    Практически в любом API, где имеется какая-то связность между объектами («сообщения пользователя», «комментарии к новости»), выстраиваются отношения один-к-одному и один-ко-многим.

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

                    При моделировании этого домена вполне можно решить, что комментарии к новости (я просто не знаю, что вы понимаете под сообщениями пользователя) — это часть агрегата (здравствуй, DDD) «новость», и это классическое отношение композиции (которое классическими РСУБД адекватно не моделируется).


              1. lair
                03.09.2015 08:44

                Что вы вкладываете в понятие «реляционным» во фразе «сделать HTTP реляционным», и в каких реализациях REST вы это видели?


                1. dannote
                  03.09.2015 09:32
                  -2

                  Я тщетно пытаюсь донести мысль, что URL в REST теряет свое первоначальное значение становится и не идентификатором, а языком запросов, в чем-то подобным SQL (работающим в рамках реляционной модели), а значит, пора уменьшать прослойку кода. Особенно это актуально для single-page-applications, которые большую часть данных тянут на лету с сервера в том виде, в котором они представлены в базе данных и не стремятся выбраться за границы CRUD.

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


                  1. lair
                    03.09.2015 09:38

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

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

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

                    Какой именно? GitHub?


      1. robert_ayrapetyan
        02.09.2015 10:11
        +1

        Бизнес-логика в триггерах — это похлеще пресловутого define true false…


        1. dannote
          02.09.2015 16:04
          -1

          В триггерах — да, но кое-какие вещи сделать как view можно себе позволить.


  1. smileonl
    01.09.2015 11:22
    +5

    Как же меня раздражают подобные жёлтые заголовки для статей.
    Я читал эту статью пару недель назад и даже там до последнего думал что автор шутит ) Но нет — всё серъёзно.


    1. Shakirok
      01.09.2015 14:00

      Я тоже не люблю такие провокационные заголовки, но статья называлась так в оригинале.


  1. vaniaPooh
    01.09.2015 11:45
    +4

    К моему счастью, бэк-енд команда согласилась параллельно с RESTful запустить JSON-pure API, просто перенеся все свои методы и коды в JSON. Спустя несколько месяцев все мои знакомые, ранее использовавшие RESTful, перешли на JSON-pure, осознав, что это гораздо удобнее.

    Одну ногу я побрила…


    1. crmMaster
      01.09.2015 13:50
      +9

      А второй нет — я ее уже давно отстрелила.


  1. Envek
    01.09.2015 11:50
    +11

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

    На самом деле все эти ужасы преувеличены. Браузеры спокойно поддерживают метод DELETE (мы из приложения на Angular.js спокойно шлём запросы DELETE и PATCH пачками) и не очень стандартные коды ответов (мы так же широко используем 422 Unprocessable Entity, чтобы показать, что запрос был семантически некорректным и транзакция произведена не была и надо смотреть в тело ответа — там будут сообщения об ошибках).


    1. jrip
      01.09.2015 14:04

      Браузеры то да, а вот серверное нестандартное не факт.
      Если смотреть стандартный случай, клиент + api, то обычно все ок, но на практике часто бывают взаимные взаимодействия с различными сервисами, а везде реализовывать RESTful задолбаешься.


    1. VolCh
      03.09.2015 21:12
      -1

      Они их поддерживают только в JS, в html — нет


      1. lair
        03.09.2015 21:15
        -1

        А как вы себе представляете работу с REST API из HTML? Они в общем-то и не для этого придуманы.


  1. hmspns
    01.09.2015 12:12
    +4

    Как по мне, самый большой недостаток REST — высокие затраты времени на разработку. Если API предоставляется через SOAP (так поступает большинство крупных компаний банковского, страхового и других B2B секторов), достаточно взять кодогенератор, который из WSDL файла сгенерирует прокси классы и всё, через 3 минуты ты можешь делать запросы, при этом особенности транспорта тебя не волнуют. Круче всего это реализовал Microsoft в своём WCF, где через конфигурационный файл можно выбрать любой транспорт, от http(s) до MSMQ (включая tcp и named pipes). WSDL файл и SOAP автоматически генерируются на основе кода.

    А REST, вот я так в толк и не возьму, какие у него основные плюсы. Меньше данных передаётся? В мире единицы сайтов, для которых экономия на траффике в таких масштабах превысит стоимость разработки REST.
    Всё структурно? Да хз, как бы да, но реально дебажить приходится смотря на все 7 мест, указанных в статье. И опять же, если следовать RESTful, то те моменты, которые через RPC решаются за один запрос, через RESTful за кучу. Не понимаю я его смысл как «эталона», короче.


    1. lair
      01.09.2015 12:29
      +12

      Если 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-инфраструктуру (например, кэширование)
      (ц) «встроенная» мультиформатность
      (д) более очевидная семантика


      1. hmspns
        01.09.2015 13:13
        +5

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

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

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

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

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

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

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

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


        1. lair
          01.09.2015 13:22
          +3

          Если API кривой, то не важно REST он, не REST, проблемы всё равно будут.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

          CORS.


          1. hmspns
            01.09.2015 13:52
            +2

            Ну конечно 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 позволяет экономить время на разработке клиента, а в ряде случаев и сервиса. Вы с этим принципиально не согласны?


            1. lair
              01.09.2015 14:23

              Ну конечно 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), то выяснится, что различия более архитектурные, чем временные, и именно от архитектуры и надо плясать.


              1. lair
                01.09.2015 14:41

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

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


              1. hmspns
                01.09.2015 14:57
                +2

                Вот здесь:

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

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

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

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

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

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

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

                Обоснуйте

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

                А SOAP и RPC — не архитектура? И что такое временные различия?


                1. lair
                  01.09.2015 15:09

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

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

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

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

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

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

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

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

                  Обоснуйте

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

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

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

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


                  1. hmspns
                    01.09.2015 15:38
                    +1

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

                    В этом утверждении говорится только о запросах, не о том, что 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) по определению с этой стороны гораздо более гибкие.


                    1. lair
                      01.09.2015 15:51

                      Но если 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 — хороший. А я считаю, что каждый из них подходит для своей задачи, а для каких-то задач подходит что-то третье.


                      1. hmspns
                        01.09.2015 16:39
                        +1

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

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

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

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

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

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


                        1. lair
                          01.09.2015 16:54

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

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

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

                          Это пока еще не SOAP, а WCF. С кем совместима эта реализация (насколько я понимаю, там WS-AT)?


                1. vedenin1980
                  01.09.2015 21:45

                  это не отменяет необходимость формирования 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 тыс. строк.


    1. kr41
      01.09.2015 12:49
      +4

      Основной плюс REST в том, что любой программист может взять свой любимый язык программирования и за пару часов написать на нем клиента к любому REST-сервису. В случае с RPC, если генератор прокси-классов для любимого языка кривой, то придется либо пилить напильником, либо использовать нелюбимый язык. У меня так было со Thrift 3 года назад. В Java он работал как часы, а в Python — баг на баге. Может быть сейчас и пофиксили, но желания использовать его с тех пор нету.


      1. hmspns
        01.09.2015 13:16
        -3

        Ну это же проблема не RPC, а конкретной реализации кодогенератора.


        1. kr41
          01.09.2015 13:41
          +6

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

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


    1. potan
      01.09.2015 12:57
      +2

      Разработка и синхронизация с кодом на scala/java/c# файлов WDSL требует времени и сил. И специальных инструментов — синтаксис ужасен, лично я в vim я такое редактировать не способен.

      Отладка RESTful-подобных интерфейсов как раз удобна, используя curl или powershell Invoke-RestMethod из командной строки.


      1. hmspns
        01.09.2015 13:14
        +1

        Не уверен, что использовать vim для разработки на C# хорошая идея, есть специализированные инструменты, типа студии (которая бесплатная в community edition), в которой таких проблем нет.


    1. velvetcat
      01.09.2015 21:29

      WSDL файл и SOAP автоматически генерируются на основе кода.

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

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


      1. lair
        01.09.2015 21:44
        +1

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

        Так что применение головы все же обязательно.


        1. Chikiro
          02.09.2015 23:48

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


          1. lair
            02.09.2015 23:49

            Потому и кавычки.

            Речь о том, что если не понимать методологию, то можно наплодить кривой API где угодно.


  1. bogus92
    01.09.2015 12:22
    +4

    JSON-RPC 2.0? Там еще и batch запросы можно делать.


  1. zelyony
    01.09.2015 12:44

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


    1. lair
      01.09.2015 13:02

      но если бы вам пришлось их формировать — без сторонних либок REST или SOAP — вы бы стали морочиться с полным HTTP-REST или простым HTTP-GET/POST и JSON/XML?

      Конечно, стали бы. Намного проще отправить пустой запрос DELETE uri, чем формировать тело сообщения с командой и идентификатором.


  1. willson
    01.09.2015 13:02
    +3

    Жду перевода статьи «JSONpure API — большая ложь», где главным аргументом против будет указана нетипизированность данных и хорошо если будет в качестве решения какой-нибудь edn, ато ведь и к XML вернемся, как расширяемой и самоописываемой обертке.


  1. jonic
    01.09.2015 13:28
    +3

    Отлично, теперь я знаю как называется то что я использую.


    1. Shakirok
      01.09.2015 13:44
      +1

      У меня была похожая реакция)


  1. jrip
    01.09.2015 13:56
    +2

    Проблема RESTful в том что мало кто делает именно точно RESTful, почти у всех какие-то особенности и оговорки.
    Да и он далеко не все проблемы решает связанные с взаимодествие с API.

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


  1. orcy
    01.09.2015 14:42
    +2

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

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


  1. mikolalex
    01.09.2015 15:26
    +5

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


    1. mayorovp
      01.09.2015 16:02
      +2

      Извиняюсь, но почему вы противопоставляете SOAP и stateless? Много веб-сервисов именно stateless и являются, более того — именно такие сервисы и рекомендуется делать.


      1. mikolalex
        01.09.2015 17:14

        Потому что rest — stateless, а soap — нет. Мне больше нравится stateless подход, и то, что rest его использует, я считаю большим плюсом rest'а.

        Много веб-сервисов именно stateless и являются, более того — именно такие сервисы и рекомендуется делать.

        Да, полностью согласен, а к чему вы повторили общеизвестный факт?


        1. mayorovp
          01.09.2015 18:19

          Потому что rest — stateless, а soap — нет.
          С чего бы? SOAP over HTTP — ничуть не менее stateless, чем REST.


          1. mikolalex
            01.09.2015 18:56

            это популярное заблуждение, почитайте:
            http://www.ibm.com/developerworks/library/ws-spmyths/
            over HTTP или нет, значения не имеет.
            REST же stateless по своему определению.


            1. mayorovp
              01.09.2015 19:01

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

              Но если вам нравится stateless подход — ничто не мешает использовать его совместно с SOAP.


              1. mikolalex
                01.09.2015 19:25
                -1

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


                1. lair
                  01.09.2015 20:24

                  Это в каких же случаях состояние в соапе неизбежно?

                  (я надеюсь, мы говорим про техническое состояние, а не бизнес)


    1. Chikiro
      02.09.2015 23:52

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


  1. voidnugget
    01.09.2015 15:58

    Для того что бы решить проблемы упомянутые в статье — нужно использовать гипермедиа типы (hateoas).
    Но там такой сыр-бор твориться…

    * У Swagger'a, в этой роли, пока что ничего не получается, и поддержка довольно ужасна.


  1. Alexeyco
    01.09.2015 16:39
    -1

    Одно могу сказать — автор этой статьи достиг своей цели: бурление говен. Теперь и на Хабре. В общем-то, во время чтения меня сначала тоже подорвало, но читая дальше и дальше, я понял, что меня попросту троллят. И я успокоился…


    1. Ununtrium
      01.09.2015 16:43
      -2

      Теперь мнение невежд высказанное в письменной форме называется троллинг? :)


      1. Alexeyco
        01.09.2015 17:15

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


  1. forgotten
    01.09.2015 16:58
    +5

    Такой срач стоит вокруг совершенно пустой статьи.

    Достаточно заметить, что автор попросту не знает, что такое 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.


    Здесь я сломался и дальше не читал.


    1. MuLLtiQ
      01.09.2015 17:30
      -3

      Да троллинг это, причем весьма толстый


    1. jrip
      02.09.2015 01:55
      +1

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

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

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

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

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

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

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

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


      1. forgotten
        02.09.2015 09:00
        -2

        > Простите, но вы тоже фигню всякую пишите :)

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

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

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

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

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

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

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

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

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

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

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


        1. forgotten
          02.09.2015 09:06

          > множественное лицо второго рода настоящего времени

          Тьфу, множественное число второго лица, конечно же.


        1. jrip
          02.09.2015 10:02

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

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

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

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

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

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

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

          >Эта схема может работать если и только если все промежуточные
          >узлы понимают и правильно интерпретируют семантику HTTP.
          Так Rest то тут вообще причем?


          1. forgotten
            02.09.2015 10:14
            +1

            Абсолютно ни при чём, вы совершенно правы.


    1. Chikiro
      02.09.2015 23:56
      -1

      — отсутствие состояний: все детали операции содержатся в самой операции; т.е. в парадигме REST нельзя сделать вот так:
      DELETE /user/data

      Можно, если у вас есть ресурс по адресу test.ru/user/data, url — всего лишь идентификатор ресурса, REST не навязывает никаких правил по именованию и иерархии.


  1. shamanis
    03.09.2015 13:05

    Ну не знаю, мне после мамонтообразного SOAP и такого-же JSON-RPC REST кажется наиболее лаконичным методом реализации API. По поводу дебага, например на Django можно отлично писать Unit-тесты, если вы пользуетесь rest_framework. Извините заранее, все комментарии не читал. Статья, имхо, вброс и скрытый пиар.


  1. Tab10id
    06.09.2015 17:40
    +2

    Удивлен что никто не написал про ограничения метода GET, в случаях каких-нибудь query-запросов частенько помещаются не все параметры и приходится, опять же, использовать POST.


  1. dmitry_pavlov
    08.09.2015 12:31

    Я согласен с автором статьи. Думаю самый хороший вариант с точки зрения разработчика — это уяснить суть RESTful сервисов, понять какие бывают типы запросов, какие из них реально поддерживаются, разобраться в кодах, в целом «подружиться» с каналом передачи протоколом HTTP и т.п. Все это даст понимание технологии и знания как правильно с ней работать. Дальше действительно удобней использовать только POST и с помощью JSON уже формировать удобную для себя структуру пакета сообщений, реализовывая по сути старый добрый request/response подход, который зарекомендовал себя давно и использовался почти во всех системах и технология сетевого взаимодействия. Надо заметить при этом, что в своих сообщениях разработчик может поддерживать принципы REST, введя свои типы сообщений для CRUD операций и поддерживая логику их обработки. HTTP в данном случае будет просто транспортом. Отвязка от канала передачи — это (опятьже согласен с автором) большой плюс.


    1. lair
      08.09.2015 12:37

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

      Не может. Использовать POST для чтения данных — противоестественно для REST.


      1. jrip
        08.09.2015 12:53

        А если при получении данных у нас ацкая куча фильтров и в GET мы не влезаем? :)


        1. lair
          08.09.2015 12:55

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


          1. jrip
            08.09.2015 12:57

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


            1. lair
              08.09.2015 12:59

              Не спорю. Но если вы их не используете — то у вас уже не REST (по крайней мере, в контексте данной операции/ресурса).


              1. jrip
                08.09.2015 13:04

                Ну в том то и прикол, я вот например не видел ни одного большого проекта, где реально REST, а не «ну почти REST». И все споры где что и как должно быть по канонам — они бессмысленны и выдают возможный недостаток опыта :)


                1. lair
                  08.09.2015 13:15

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


                  1. jrip
                    08.09.2015 13:38

                    >Споры «как должно быть по канонам» имеют смысл, чтобы понимать, куда стремиться
                    Зачем спорить о том, что четко описано?

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


                    1. lair
                      08.09.2015 13:48

                      Зачем спорить о том, что четко описано? [...] Для того чтобы понять, что есть restful спорить смысла нет, достаточно почитать.

                      Как видно из дискуссий — описано недостаточно четко, чтобы все понимали.


      1. dmitry_pavlov
        08.09.2015 13:29

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

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


        1. jrip
          08.09.2015 13:42

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

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

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

          А это еще хуже, когда REST называют то, что им не является и путают людей.


        1. lair
          08.09.2015 13:47

          Нельзя «перенести принципы REST внутрь сообщений», об этом и речь. Получите вы обычный RPC, коим много лет уже.


          1. dmitry_pavlov
            08.09.2015 23:38
            -1

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


            1. lair
              08.09.2015 23:48
              +2

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


              1. dmitry_pavlov
                09.09.2015 12:26
                -2

                Дао Вебсервиса. (Или да хватит же изобретать велосипеды!) — http://habrahabr.ru/post/75248/


                1. lair
                  09.09.2015 12:30

                  Угу. Уже сильно больше одного раза обсудили все проблемы SOAP, надо еще раз повторить?


                  1. dmitry_pavlov
                    09.09.2015 12:34

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


                    1. dmitry_pavlov
                      09.09.2015 12:41
                      -3

                      И хватит минусовать — это как-то глупо что ли. Моя точка зрения имеет такое же а то и большее право на существование по сравнению с вашей :)


                    1. lair
                      09.09.2015 12:52

                      Архитектура (в том числе хорошая), поддерживаемость, тестируемость — это все «понятия». За ними тоже не надо гнаться?

                      Никто не считает REST священной коровой. Это конкретный подход с весьма конкретными ограничениями. Кому ограничения не нравятся — окей, пожалуйста, сколько угодно, можете не использовать, можете даже ругать и говорить, что другая технология лучше; но зачем называть то, что вы используете вместо REST — REST?


                      1. dmitry_pavlov
                        09.09.2015 16:01

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

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

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

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

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


                        1. lair
                          09.09.2015 16:07

                          Да, тоже не надо гнаться. Любая идея, возведенная в абсолют

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

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

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


                          1. dmitry_pavlov
                            09.09.2015 16:46

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

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

                            Утомился я пререкаться. Думаю, продолжать не уже буду. Спасибо за дискуссию.


                            1. lair
                              09.09.2015 16:48

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

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

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

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