Rest soap что это
Rest soap что это
Eсть два основных подхода к построению программного интерфейса веб-приложений: REST (RESTful) API и SOAP API:
Подробнее:
REST (Representational State Transfer — «передача состояния представления») — архитектурный стиль взаимодействия компонентов распределённого приложения в сети.
REST представляет собой согласованный набор ограничений, учитываемых при проектировании распределённой гипермедиа-системы. В определённых случаях (интернет-магазины, поисковые системы, прочие системы, основанные на данных) это приводит к повышению производительности и упрощению архитектуры. В широком смысле компоненты в REST взаимодействуют наподобие взаимодействия клиентов и серверов во Всемирной паутине.
В сети Интернет вызов удалённой процедуры может представлять собой обычный HTTP-запрос (обычно «GET» или «POST»; такой запрос называют «REST-запрос»), а необходимые данные передаются в качестве параметров запроса.
Для веб-служб, построенных с учётом REST (то есть не нарушающих накладываемых им ограничений), применяют термин «RESTful».
В отличие от веб-сервисов (веб-служб) на основе SOAP, не существует «официального» стандарта для RESTful веб-API.
REST является архитектурным стилем, в то время как SOAP является протоколом. Несмотря на то, что REST не является стандартом сам по себе, большинство RESTful-реализаций используют стандарты, такие как HTTP, URL, JSON и XML.
Требования архитектуры REST:
5. Слои
Клиент обычно не способен точно определить, взаимодействует он напрямую с сервером или же с промежуточным узлом, в связи с иерархической структурой сетей (подразумевая, что такая структура образует слои). Применение промежуточных серверов способно повысить масштабируемость за счёт балансировки нагрузки и распределённого кэширования. Промежуточные узлы также могут подчиняться политике безопасности с целью обеспечения конфиденциальности информации.
6. Код по требованию (необязательное ограничение).
REST может позволить расширить функциональность клиента за счёт загрузки кода с сервера в виде апплетов или сценариев.
Приложения, не соответствующие приведённым условиям, не могут называться REST-приложениями.
Если же все условия соблюдены, то приложение получает следующие преимущества:
Преимущества:
• Надёжность (за счёт отсутствия необходимости сохранять информацию о состоянии клиента, которая может быть утеряна);
• Производительность (за счёт использования кэша);
• Масштабируемость;
• Прозрачность системы взаимодействия (особенно необходимая для приложений обслуживания сети);
• Простота интерфейсов;
• Портативность компонентов;
• Лёгкость внесения изменений;
• Способность эволюционировать, приспосабливаясь к новым требованиям (на примере Интернет).
SOAP (Simple Object Access Protocol — простой протокол доступа к объектам) — протокол обмена структурированными сообщениями в распределённой вычислительной среде.
Первоначально SOAP предназначался в основном для реализации удалённого вызова процедур. Сейчас протокол используется для обмена произвольными сообщениями в формате XML, а не только для вызова процедур.
SOAP может использоваться с любым протоколом прикладного уровня: SMTP, FTP, HTTP, HTTPS и др. Однако его взаимодействие с каждым из этих протоколов имеет свои особенности, которые должны быть определены отдельно. Чаще всего SOAP используется поверх HTTP.
SOAP является одним из стандартов, на которых базируются технологии веб-служб.
Рельсы веб-интеграции. REST и SOAP
В каждой отрасли бизнеса, каждой компании, как правило, используется целый зоопарк ПО. Одни системы «из коробки» умеют взаимодействовать с «соседними» продуктами, другие же приходится дорабатывать. За десятилетия существования веба как отрасли сформировались следующие практики межсетевого взаимодействия:
Обмен файлами по FTP.
Неструктурированные HTTP-запросы, договорённости между разработчиками.
Экзотика: сокеты, порты, бинарные объекты.
В данной статье мы поговорим о веб-сервисах. Чем они отличаются от прочих способов и какие они бывают.
Что такое веб-сервисы?
Веб-сервисы (или веб-службы) — это технология, позволяющая системам обмениваться данными друг с другом через сетевое подключение. Обычно веб-сервисы работают поверх протокола HTTP или протокола более высокого уровня. Веб-сервис — просто адрес, ссылка, обращение к которому позволяет получить данные или выполнить действие.
Главное отличие веб-сервиса от других способов передачи данных: стандартизированность. Приняв решение использовать веб-сервисы, можно сразу переходить к структуре данных и доступным функциям. Например, в SOAP (как более строгом протоколе), уже решён вопрос уведомления об ошибках.
Самые известные способы реализации веб-сервисов:
XML-RPC (XML Remote Procedure Call) — протокол удаленного вызова процедур с использованием XML. Прародитель SOAP. Предельно прост в реализации.
SOAP (Simple Object Access Protocol) — стандартный протокол по версии W3C. Четко структурирован и задокументирован.
JSON-RPC (JSON Remote Procedure Call) — более современный аналог XML-RPC. Основное отличие — данные передаются в формате JSON.
REST (Representational State Transfer) — архитектурный стиль взаимодействия компьютерных систем в сети основанный на методах протокола HTTP.
Специализированные протоколы для конкретного вида задач, такие как GraphQL.
Менее распространенный, но более эффективный gRPC, передающий данные в бинарном виде и использующий HTTP/2 в качестве транспорта.
Остальные протоколы не так широко распространены. Подробно рассмотрены в статье будут SOAP и REST.
SOAP (Simple Object Access Protocol) — данные передаются в формате XML.
отраслевой стандарт по версии W3C;
наличие строгой спецификации;
широкая поддержка в продуктах Microsoft,
сложность/ресурсоемкость парсинга XML-данных.
Любое сообщение в протоколе SOAP — это XML документ, состоящий из следующих элементов (тегов):
Envelope. Корневой обязательный элемент. Определяет начало и окончание сообщения.
Header. Необязательный элемент — заголовок. Содержит элементы, необходимые для обработки самого сообщения. Например, идентификатор сессии.
Body. Основной элемент, содержит основную информацию сообщения. Обязательный.
Fault. Элемент, содержащий информацию об ошибках, возникающих в процессе обработки сообщения. Необязательный.
Пример SOAP запроса:
Пример SOAP ответа:
REST (Representational State Transfer) — на самом деле архитектурный стиль, а не протокол. В отличие от SOAP, REST не подкреплен официальным стандартом. Фактически, он основывается на соглашениях. Веб-сервис, построенный с учетом всех требований и ограничений архитектурного стиля, можно назвать RESTful веб-сервисом.
REST не использует конвертацию данных при передаче, данные передаются в исходном виде — это снижает нагрузку на клиент веб-сервиса, но увеличивает нагрузку на сеть. Управление данными происходит с помощью методов HTTP:
GET — получить данные;
POST — добавить данные;
PUT — изменить данные;
DELETE — удалить данные.
Использование этих методов позволяет реализовать типичный CRUD (Create/Read/Update/Delete) для любой информации. Но это лишь соглашение: часто используются только 2 метода: GET для получения и POST для всего остального. Разобраться поможет такое понятие, как REST-Patterns. Паттерны связывают HTTP методы с тем, что они делают.
экономичность в плане ресурсов;
не требует программных надстроек (json_decode есть почти в каждом языке).
неоднозначность методов управления данными.
Пример REST запроса:
Пример REST ответа:
Что же использовать?
Вопрос «Какой способ реализации использовать?» необходимо рассматривать в контексте реализуемой системы и ее ограничений. Обычно, SOAP используется в крупных корпоративных системах со сложной логикой, когда требуются четкие стандарты, подкрепленные временем. XML-RPC, пожалуй, устарел и не имеет смысла ввиду наличия собрата JSON-RPC. RPC-протоколы подойдут для совсем простых систем с малым количеством единиц информации и API-методов.
Если же вы разрабатываете публичное API и логика взаимодействия во многом покрывается четверкой методов CRUD — смело выбирайте REST. Он наиболее популярен в WEB. Яндекс, Google и другие используют именно его для своего API.
Веб-сервисы в живом производстве
Разработка веб-сервисов — типичная задача интеграции. ИНТЕРВОЛГА, как веб-интегратор, регулярно сталкивается с задачами разработки веб-сервисов и успешно с ними справляется. Наши сайты были и SOAP/REST серверами, и SOAP/REST клиентами.
Успешным примером внедрения веб-сервисов является проект Enterprise-уровня — Личный кабинет клиентов компании Евраз Металл Инпром. Все функции личного кабинета основываются на взаимодействии с удаленным SOAP веб-сервисом. Сайт выступает клиентом. В процессе эволюции в угоду безопасности сайт переквалифицировался в SOAP-сервер, а учетная система в SOAP-клиента.
Еще один личный кабинет для клиентов компании Евраз — еще один пример сайта в качестве клиента удаленного SOAP веб-сервиса.
Если у вас есть потребность организовать взаимодействие с веб-сервисом, сделать из сайта REST/SOAP/RPC клиент или сервер, пишите нам.
Подведем итог, выделив, два важных тезиса в пользу выбора веб-сервисов в качестве «рельс» для веб-интеграции.
Наш опыт неоднократно демонстрировал, что создание веб-сервисов, в реальном времени передающих необходимые данные между сайтом и другим ПО — лучшее решение, чем классические обмены по расписанию. Такой подход проще сопровождать, вести его отладку, это более эффективная трата времени программиста, чем проектирование и разработка сложного двунаправленного обмена с кучей сущностей.
Можно провести аналогию с эволюцией разработки сайтов. Когда-то, на заре сайтостроения, каждый разработчик делал сайт с нуля на той технологии, которую мог знать лишь он один. Это порождало проблемы в развитии таких сайтов. Как работали такие сайты — знал только автор кода. Со временем появлялись фреймворки и CMS. Разработку начинали не с нуля, а с известных широкой массе разработчиков «заготовок» — стандартных решений стандартных проблем с возможность расширения и углубления.
Также и с обменом данными. Не нужно тратить месяцы на объяснение новому сотруднику и самому себе, как работает обмен. Есть стандарт, обмен работает по нему.
REST vs SOAP. Часть 2. Как проще и эффективнее организовать общение платформ?
Оглавление цикла статей:
REST vs SOAP. Часть 1. Почувствуйте разницу.
REST vs SOAP. Часть 2. Как проще и эффективнее организовать общение платформ?
Зачем все это?
Зачем вообще нужно взаимодействие приложений, тем более написанных на разных платформах? Глупый вопрос, конечно. В мире программирования параллельно существуют и развиваются несколько абсолютно независимых, а местами и враждующих платформ. Кроме того, огромное количество софта уже написано и успешно работает, поэтому переписывать его под каждую новую платформу никто не будет. Возьмем банк для примера. Все in-house программисты банка всегда писали на JAVA, поэтому у банка есть сервис, который уже 5 лет прекрасно работает, недавно появились красивые мобильные приложения на Android, которые стабильно работают почти на всех версиях ОС, и остался даже сайт с апплетом, которых преподаватели в харьковских вузах до сих показывают в качестве примера передовых веб-технологий (jk). А теперь появилась задача разработки десктопного банковского приложения под Windows. Банк заказал WPF-приложение аутсорсинговой компании. Как же организовать общение платформ?
Немного истории
SOAP также появился в 1998 году стараниями Microsoft. Он был анонсирован как революция в мире ПО. Нельзя сказать, что все пошло по плану Microsoft, было огромное количество критики из-за сложности и тяжеловесности протокола. В то же время были и те, кто считал SOAP настоящим прорывом. Сам же протокол продолжал развиваться и плодиться десятками новых и новых спецификаций, пока в 2003 года W3C не утвердила в качестве рекомендации SOAP 1.2, который и сейчас является последним. Семейство у SOAP получилось внушительное, вот их семейная фотография:
(на фото — WS-Addressing, WS-Enumeration, WS-Eventing, WS-Transfer, WS-Trust, WS-Federation, Web Single Sign-On… А того второго справа вообще не вспомнить, как зовут)
За более десяти лет споры по поводу SOAP не утихли, он по прежнему яростно критикуется за перегруженность, за низкую скорость работы. Однако протокол не умер, скорее даже наоборот, хотя и мир тоже не захватил. Критика протокола во многом справедлива: не используются заложенные в HTTP фичи, длина сообщений больше, чем у REST, от всех этих WS-Federation и WS-AtomicTransaction часто нету никакой пользы.
Но я хочу заострить внимание на другом – как же быстро можно разрабатывать распределенные приложения, используя семейство протоколов SOAP! Это ли не революция, которую нам обещал Microsoft? По-моему, это именно она. Где еще можно порасставлять аттрибуты в коде, нажать кнопку Publish на сервисе, нажать кнопку Generate Proxy на клиенте и вызывать код, как будто он находится в том же проекте? Поэтому на передний план выходит вопрос о том, в каких языках и средах программирования такая сказка возможна. Попробую свести эти данные в таблицу:
А как же REST, неужели он не нужен?
Дни SOAP сочтены?
Сейчас REST и SOAP оба успешно используются, однако может произойти так, что SOAP действительно исчезнет, как пишут его критики. Такое, по моему мнению, возможно, если для RESTful сервисов начнет использоваться WSDL или подобный протокол, который позволит генерировать клиентские прокси. Поползновения такие были, протокол назывался WADL, однако на данный момент ничего такого не существует. Конечно, для такого сценария потребуется желание и приличные усилия хотя бы одного из основных игроков в мире IT, но я бы не стал исключать такой вариант. И будет у нас тогда лучшее из двух миров – простота и бенефиты от архитектуры сети и автоматизация взаимодействия приложений с помощью клиентских прокси.
Пример
Все уже забыли о примере из начала статьи? Он взят из жизни. Напомню, там разрабатывается WPF приложение, которое должно получать данные из существующего сервиса, написанного на JAVA. В каком формате он мог бы нам отдавать данные чтобы все выглядело бы красиво в соответствии с этой статьей? Правильно, в SOAP. А он отдает json. Надеюсь, ни у кого не возникло мысли «какой json, это в смысле REST?». Конечно REST! REST может возвращать данные в простом XML, json или любом другом запрошенном формате, даже в формате «как Вася попросил», если вам конечно удастся сделать этот формат одним рекомендуемых стандартов W3C или хотя бы договориться с разработчиками сервиса, чтобы они знали, что делать с этим:
Content-Type: application/as-Vasya-asked; charset=utf-8
Мы отвлеклись от дела. Ну возвращает сервис данные в json, и чем это нам грозит? А вот чем: прокси клиента сгенерить не сможем, придется вручную посылать запросы и парсить ответы. Придется использовать HttpWebRequest или надстройки над ним. А был бы SOAP – деньги заказчика были бы сэкономлены.
Заключение
REST — это новый SOAP
Несколько лет назад я разрабатывал для одного большого телекома новую информационную систему. Нам приходилось взаимодействовать со всё нарастающим количеством веб-сервисов, открываемых более старыми системами или бизнес-партнёрами. Как вы понимаете, мы получили добрую порцию SOAP-ада. Заумные WSDL, несовместимые библиотеки, странные баги… Где только возможно мы старались продвинуть — и использовать — простые RPC-протоколы: XMLRPC или JSONRPC.
Наши первые серверы и клиенты, работавшие по этим протоколам, были очень простыми, со скромными возможностями и ненадёжными. Но мы постепенно их улучшали и через несколько сотен строк кода достигли желаемого:
Теперь можно было надёжно подключаться к любому подобному API с помощью лишь нескольких строк кода. И также мы теперь могли с помощью нескольких декораторов и обновлений документов открывать любой набор функций для широкой аудитории, для серверов и браузеров.
А когда дошло до взаимодействия между разными приложениями (построенными на основе микросервисов), этим уже занимался наш сисадмин. С программной частью уже практически не было никаких неясностей.
Разработчик отдыхает после трудной получасовой интеграции RPC API
А затем появился REST.
REpresentational State Transfer — передача состояния представления.
Эта новая волна сотрясла основы межсервисного взаимодействия.
RPC умер, будущее было за RESTful: ресурсы живут на своих собственных URL, а манипулировать ими можно только по протоколу HTTP.
С тех пор каждый API, который нам приходилось выставлять или к которому мы обращались, превращался в новую трудность, если не сказать — в безумие.
А что за проблема с REST?
Чтобы не описывать на пальцах, проиллюстрирую на примере. Вот маленький API, типы данных убраны для удобства чтения.
В этом API легко разобраться, его легко использовать, он надёжен. Он поддерживается точной машиной состояний (state machine), но ограниченный набор доступных операций удерживает пользователей от необдуманных действий (вроде изменения даты создания аккаунта).
Ожидаемая длительность выставления этого API в качестве простого RPC-сервиса: несколько часов.
Так, а теперь в дело вступает RESTful.
Никаких стандартов, никаких точных спецификаций. Лишь невнятная «философия REST», бесконечные дебаты и множество дурацких костылей.
Какую URL-endpoint вы присваиваете каждому «ресурсу»? Да, это просто, но приходится делать в любом случае.
Как выражаете разнообразие ошибочных состояний с помощью очень ограниченного набора HTTP-кодов?
Какие форматы сериализации, какие специфические диалекты вы используете для ввода и вывода полезных данных?
Как именно вы распределяете эти простые сигнатуры по HTTP-методам, URL, строкам запросов, полезным данным, заголовкам и кодам статуса?
И вы часами переизобретаете колесо. Причём не заточенное под вас, умное колесо, а сломанное и хрупкое. Оно нарушает спецификации, даже не замечая этого, а чтобы разобраться в колесе, нужно прочитать тома документации.
Как так вышло, что REST требует столько РАБОТЫ?
Это и парадокс, и бесстыжий каламбур (игра слов: rest может означать «отдых»).
Давайте рассмотрим искусственные проблемы, возникшие из этой философии проектирования.
Удовольствие от глагольных REST-команд
REST вам не CRUD, его сторонники будут уверять, что вы не спутаете эти два понятия. А через несколько минут они начнут радоваться, что у глагольных HTTP-команд прекрасно определённая семантика для создания (POST), получения (GET), обновления (PUT/PATCH) и удаления (DELETE) ресурсов.
Сторонники открыто восхищаются, что нескольких HTTP-команд достаточно для выражения любой операции. Конечно, достаточно. Точно так же, как горстки этих команд достаточно для выражения на английском языке любой концепции: «Сегодня обновил своим телом моё АвтомобильноеВодительскоеСиденье и создал ЗажиганиеДвигателя, но ТопливныйБак себя удалил». От того, что вы можете так сделать, результат не становится менее уродливым. Если только вы не обожаете язык токипона.
Если важен минимализм, то хотя бы делайте всё правильно. Вы знаете, почему PUT, PATCH и DELETE никогда не были реализованы в браузерных формах? Потому что они бесполезны и вредны. Нельзя просто использовать GET для чтения и POST для записи. Или выполнять POST эксклюзивно, когда нежелательно кеширование на HTTP-уровне. Остальные глагольные команды в лучшем случае будут вам мешать, а в худшем — просто испортят вам целый день.
Хотите с помощью PUT обновлять свои ресурсы? Ладно, но Пресвятые Спецификации утверждают, что ввод данных должен представлять собой «полный ресурс» (complete resource), т. е. нужно следовать той же схеме, что и у вывода данных с помощью GET. И что вы будете делать с многочисленными параметрами только для чтения, возвращаемыми командой GET (время создания, время последнего обновления, сгенерированный сервером токен…)? Вы пренебрегаете ими и нарушаете принципы PUT? Вы в любом случае их вставляете и ожидаете «конфликта HTTP 409», если они не совпадают с серверными значениями (потом заставляя вас отправлять GET…)? Вы даёте им случайные значения и ожидаете, что сервер будет их игнорировать (удовольствие от тихих ошибок)? Выберите, что вам ближе, REST не даёт ясного понимания, что такое атрибут только для чтения, в ближайшем будущем эта ситуация не изменится. При этом опасность GET в том, что он должен возвращать пароль (или номер банковской карты), который затем отправляется в предыдущий POST/PUT — удачи вам и с этими параметрами только для записи.
Хотите для обновления своего ресурса использовать PATCH? Прекрасно, но, как и 99 % людей, использующих глагольные команды, будете просто отправлять в полезных данных своего запроса подмножество полей ресурса в надежде, что сервер правильно поймёт, что вы хотели сделать (со всеми возможными побочными эффектами). Многие параметры ресурсов глубоко взаимосвязаны или обоюдно эксклюзивны (например, в данных о пользовательском счёте указывается номер банковской карты ИЛИ токен PayPal), но RESTful-архитектура скрывает и эту важную информацию. Но вы в любом случае опять нарушите спецификации: PATCH не должен отправлять кучу полей для переопределения. Он должен отправлять «набор инструкций», которые будут применяться к ресурсам. Так что берите блокнот и кружку с кофе, придётся определиться с выражением этих инструкций и их семантикой. Не-изобретённый-здесь синдром — это стандарт де-факто в мире REST.
Хотите удалять ресурсы с помощью DELETE? Ладно, но надеюсь, вам не понадобится предоставлять важную контекстную информацию типа PDF-скана пользовательского запроса о расторжении. DELETE не должен содержать полезную информацию. Этим ограничением REST-архитекторы часто пренебрегают, потому что большинство веб-серверов не заставляют соблюдать это правило в запросах к себе. Но насколько совместимым будет DELETE-запрос с прикреплённой двухмегабайтной base64-строкой запроса?
Приверженцы REST с лёгкостью заявляют, что «люди всё делают неправильно» и что их API «на самом деле не RESTful». К примеру, многие разработчики используют PUT для создания ресурсов прямо в финальном URL (/myresourcebase/myresourceid), в то время как «правильный способ» — применить POST к родительскому URL (/myresourcebase) и позволить серверу с помощью HTTP-заголовка «расположения» показать URL нового ресурса (это не HTTP-переадресация). Хорошая новость: разницы никакой. Все эти сурьёзные принципы — как споры между сторонниками Big Endian и Little Endian, философы часами переубеждают друг друга, но всё это «правильное делание» имеет очень мало отношения к реальным проблемам.
Кстати… делать URL’ы вручную всегда очень весело. Вы знаете, сколько реализаций правильно применяют urlencode() к идентификаторам при сборке REST URL’ов? Не слишком-то много. Готовьтесь к грубым вторжениям и SSRF/CSRF-атакам.
Когда вы забыли применить urlencode к именам пользователей в одном из 30 своих составленных вручную URL’ов
Удовольствие от REST-обработки ошибок
Почти каждый программист может выполнить «номинальную» работу. Обработка ошибок — одно из свойств, делающих ваш код надёжной программой или огромной кучей хлама.
HTTP из коробки предоставляет список кодов ошибок. Отлично, давайте посмотрим.
Использовать HTTP 404 Not Found для уведомления об отсутствующем ресурсе — звучит чертовски по-RESTful, верно? Паршивое решение: ваш nginx был ошибочно сконфигурирован на один час, так что пользователи вашего API получают только ошибки 404 и вычищают сотни аккаунтов, думая, что они удалены…
Наши пользователи после того, как мы по ошибке удалили гигабайты их картинок с котиками
Кажется, вполне можно выбрать HTTP 401 Unauthorized, если у пользователя нет данных для доступа к стороннему сервису? Однако если Ajax-вызов в браузер Safari получит такой код, то может напугать вашего конечного пользователя очень неожиданным запросом пароля (несколько лет назад так и происходило).
HTTP существовал задолго до появления REST, и в экосистеме веба можно найти множество толкований значений кодов ошибок. Использовать их для передачи ошибок приложения — всё равно что хранить токсичные отходы в молочных бутылках: однажды у вас неизбежно возникнут проблемы.
Некоторые стандартные коды ошибок HTTP характерны для Webdav, другие для Microsoft, а у оставшихся такие расплывчатые описания, что от них никакого толку. В результате, как и большинство пользователей REST, вы, вероятно, для выражения исключений в своём приложении используете случайные HTTP-коды вроде HTTP 418 I’m a teapot или вообще неприсвоенные номера. Или бесстыдно возвращаете HTTP 400 Bad Request на все функциональные ошибки, а затем изобретаете собственный корявый формат ошибок, с булевыми значениями, цифровыми кодами, описательными блоками и преобразованными сообщениями, засунутыми в произвольные полезные данные. Или вы вообще забиваете на корректную обработку ошибок: просто возвращаете сообщение на обычном языке в надежде, что вызывающей стороной будет человек, который сможет проанализировать проблему и принять меры. Удачи вам в общении с такими API из автономных программ.
Удовольствие от концепций REST
REST сделал карьеру на хвастовстве либо концепциями, которые и так уважает любой находящийся в здравом уме архитектор, либо принципами, которым сам REST даже не следует. Вот несколько выдержек с сайтов из первых позиций поисковой выдачи:
REST — это клиент-серверная архитектура. У клиента и сервера разные задачи.
Какая сенсация в мире разработки ПО.
REST предоставляет единый интерфейс для взаимодействия компонентов.
Ну, собственно, как и любой другой протокол, который считается лингва франка в целой экосистеме сервисов.
REST — это система, состоящая из уровней. Отдельные компоненты ограничены тем уровнем, с которым они в данный момент взаимодействуют.
Звучит как нормальное следствие любой грамотно спроектированной, слабо взаимосвязанной архитектуры. Невероятно.
REST замечательный, потому что он не отслеживает состояния (stateless).
Быть может, за каким-то веб-сервисом скрывается огромная база данных, но сервис не помнит состояния клиентов. Ну, он помнит сессии аутентификации, разрешения доступа… но всё же он не отслеживает состояния. Точнее, он их не отслеживает в той же мере, что и любой протокол на основе HTTP, вроде того же RPC.
С помощью REST вы можете управлять мощью HTTP-кеширования!
Тут можно сделать как минимум одно заключение: GET-запрос и его заголовки управления кешированием хорошо ладят с веб-кешами. Получается, локальных кешей (Memcached и т. д.) достаточно для 99 % веб-сервисов? Неуправляемые кеши — это опасные чудовища. Кто из вас хочет открывать свои API в чисто текстовом формате, чтобы какой-нибудь Varnish или прокси мог доставлять устаревший контент намного позже обновления или удаления ресурса? Возможно даже, чтобы мог доставлять «вечно» в случае ошибки в конфигурации? Система должна быть безопасной по умолчанию. Я искренне признаю, что некоторые высоконагруженные системы нуждаются в HTTP-кешировании, но гораздо дешевле открывать несколько конечных точек GET для тяжёлых операций только для чтения, а не переводить все операции на REST с его сомнительной обработкой ошибок.
Благодаря этому REST обладает высокой производительностью!
Мы в этом уверены? Любой проектировщик API знает: локально нам нужны мелкие API, чтобы можно было делать что захочется; а удалённо нам нужны крупные API, чтобы уменьшить влияние обменов данными по сети между клиентом и сервером. И здесь REST тоже с треском проваливается. Распределение данных по «ресурсам», каждый экземпляр на своей собственной конечной точке, приводит к проблеме N + 1 запросов. Чтобы получить все пользовательские данные (аккаунт, подписки, информация о счёте…) — вам придётся сделать N + 1 HTTP-запросов. И вы не сможете их распараллелить, потому что не знаете заранее уникальные ID связанных ресурсов. Это, а также невозможность извлечь только часть объектов ресурса, превращается в самое настоящее узкое место.
У REST лучше совместимость.
Это как? Почему тогда так много REST веб-сервисов содержат в своих базовых URL’ах “/v2/” или “/v3/”? C помощью высокоуровневых языков не так уж трудно реализовать API, совместимые вперёд и назад, пока вы следуете простым правилам при добавлении/избегании параметров. Насколько я знаю, REST не привносит сюда ничего нового.
REST прост, все знают HTTP!
Ну, все знают и про валуны, только люди предпочитают строить дома из более удобных материалов. Точно так же XML — метаязык, к HTTP — метапротокол. Чтобы получить настоящий протокол уровня приложения (чем являются «диалекты» по отношению к XML), вам придётся очень много всего определить. И в результате вы получите Ещё Один Протокол RPC, как будто мало уже имеющихся.
REST так прост, по нему можно из оболочки делать запросы с помощью CURL!
На самом деле с помощью CURL можно обращаться по любому протоколу на основе HTTP. Даже по SOAP. Нет ничего сложного в отправке GET-команд, но желаю вам удачи в написании вручную JSON- или XML-полезных данных в POST-командах. Обычно люди используют вспомогательные файлы или, что гораздо удобнее, эффективные API-клиенты, инстанцируемые прямо в командной строке интерфейсов разных языков программирования.
Чтобы клиент мог пользоваться сервисом, ему не нужно ничего знать заранее об этом сервисе.
Моя любимая цитата. Я встречал её множество раз, в разных формулировках, зачастую в сочетании с модным выражением HATEOAS; иногда после неё ставят осторожные (но бесполезные) фразы об «исключениях». Я не знаю, в каком мире фантазий живут эти люди, но в нашем мире клиентская программа — это не муравейник. Она не обращается случайным образом к удалённым API, решая потом, как лучше всего их обработать: с помощью шаблонов распознавания или чёрной магии. У клиента есть конкретные ожидания: с помощью PUT передать это поле с этим значением вон тому URL’у, а и серверу лучше уважать семантику, согласованную при интеграции, иначе может начаться ад.
Когда спрашиваешь, как же работает HATEOAS
Как делать REST правильно и быстро?
Забудьте о «правильно». REST — это как религия, ни один смертный не сможет постичь всех высот его гениальности и «сделать правильно».
Правильный вопрос: если вам приходится открывать веб-сервисы в RESTful-стиле или работать с ними, как можно поскорее закончить с этим и перейти к более конструктивным задачам?
Как индустриализировать выставление серверной части?
У каждого веб-фреймворка свой способ определения URL-конечных точек. Так что если нужно воткнуть в ваш любимый сервер имеющийся API в качестве REST-конечной точки, то готовьтесь к большим зависимостям или к доброй порции шаблонного кода, который придётся писать вручную.
Библиотеки вроде Django-Rest-Framework автоматизируют создание REST API, действуя по принципу ориентированных на обработку данных обёрток вокруг SQL/noSQL-схем. Если вам просто нужен «CRUD поверх HTTP», то проблем с ними не будет. Но если вам нужно выставлять настоящие API с рабочими процессами, ограничениями и всем прочим, то придётся долго обрабатывать любой REST-фреймворк напильником, чтобы подогнать под свои нужды.
Приготовьтесь один за другим соединять каждый HTTP-метод с каждой конечной точкой, с соответствующим вызовом метода. Придётся вручную обработать немало исключений, чтобы преобразовать транзитные исключения в соответствующие коды ошибок и полезную информацию.
Как индустриализировать клиентскую интеграцию?
По моему опыту, никак.
Придётся читать длинную документацию для каждой интеграции API и следовать подробным инструкциям выполнения каждой из N возможных операций.
Придётся вручную собирать URL’ы, писать сериализаторы и десериализаторы, а также изучать, как закостылить неясности API. Укрощать чудовище будете методом проб и ошибок.
Вы знаете, как поставщики веб-сервисов компенсируют это и облегчают внедрение?
Они просто пишут собственные официальные реализации клиентов.
ДЛЯ. КАЖДОГО. ОСНОВНОГО. ЯЗЫКА. И. ПЛАТФОРМЫ.
Каждый клиент живёт в собственном Github-репозитории. У каждого собственные длинные списки коммитов, отчётов о багах и pull-реквестах. Каждый со своими примерами использования. У каждого своя вычурная архитектура, что-то среднее между ActiveRecord и RPC-прокси.
Это поразительно. Сколько времени потрачено на эти странные обёртки вместо улучшения нормальных, ценных, эффективных веб-сервисов.
Сизиф разрабатывает Ещё Один Клиент для своего API
Заключение
В течение десятилетий почти все языки программирования использовали один рабочий процесс: входные данные отправляли тому, кого можно вызвать, а в качестве выходных данных получали результат или ошибки. Всё работало. И неплохо.
А с REST всё превратилось в безумие: сопоставляем яблоки с апельсинами, восхваляем HTTP-спецификации, чтобы через минуту их лихо нарушить.
Почему такая простая задача — соединение библиотек по сети — остаётся настолько сложным и трудоёмким делом? И это происходит в эпоху, когда микросервисы становятся обычным делом.
Не сомневаюсь, что какие-нибудь умники приведут в пример ситуации, когда REST проявляет себя во всей красе. Эти люди покажут свои собственные протоколы на основе REST, которые благодаря гиперссылкам позволяют работать с деревьями произвольных объектов и применять к ним CRUD-операции. Эти люди расскажут о замечательных свойствах REST-архитектуры, отметят, что я не прочитал достаточно статей и диссертаций, посвящённых этим концепциям.
Мне плевать. Деревья оценивают по плодам. Решения, на которые с простым RPC у меня уходило несколько часов написания кода и которые работали очень надёжно, теперь требуют недель труда и бесконечного изобретения новых неудачных подходов или нарушения ожиданий. Разработку заменило латание дыр.
Почти прозрачные RPC удовлетворяли 99 % людей, а имеющиеся протоколы, пусть и несовершенные, прекрасно работали. А этот массовый монопсихоз, связанный с наименьшим общим знаменателем веба — HTTP, — в основном привёл к огромным потерям времени и серого вещества.
REST обещал простоту, а принёс сложность.
REST обещал надёжность, а принёс хрупкость.
REST обещал совместимость, а принёс неоднородность.
REST — это новый SOAP.
Эпилог
Будущее может быть светлым. Есть множество превосходных протоколов, бинарных и текстовых, со схемами и без, некоторые используют новые возможности HTTP2… так давайте двигаться дальше. Нельзя вечно оставаться в каменном веке веб-сервисов.
Многие спрашивают меня об этих протоколах, эта тема заслуживает отдельной истории. Но вы можете обратить внимание на XMLRPC и JSONRPC, или на характерные для конкретных языков слои вроде Pyro или RMI для внутреннего использования, или на новичков вроде GraphQL и gRPC для публичных API…