Work: REST Batching, part I

Jan 20, 2009 02:13




HTTP внутри HTTP это, как реторта с
личинками дельфинов - вещь в себе

Если вы разрабатываете REST API, то рано или поздно к вам придут ваши клиенты с просьбой сделать пакетную обработку. Сделать так, что бы сервер приимал произвольный набор запросов одним пакетом и отправлял назад все результаты тоже одновременно. Это касается не только GET запросов, а любых методов - PUT, POST, DELETE и т.д. Ответы тоже будут разные, и будут содержать различные типы данных - например текст в различных encoding-ах и charset-ах, или двоичные данные в произвольном формате. В общем случае, скажут они, было бы полезно уметь обрабатывать пакеты любых HTTP запросов, в том числе запросы к внешним серверам которые необходимо исполнить последовательно с запросами к серверам из локальной сети.

С первого взгляда это кажется замечательной идеей. Клиент делает единственный POST запрос, получает единственный ответ и здорово экономит на сетевых задержках. На самом деле, здесь столько подводных камней, что вы сможете пожалеть что вообще с этим связались. Но выбора обычно нет. Что же тут плохого? Посмотрим сначала на
Религиозные проблемы REST
  • Очевидно, что URI этого прокси одинаков для пакетов любых запросов - на вход поступауют произвольные запросы, на выходе мы имеет произвольные ресурсы. Значит этот URI перестаёт уникально идентифицировать ресурсы которые этот прокси обрабатывает
  • Требуемая операция содержится не в HTTP verb, а в теле запроса. И несмотря на то, что POST request вроде как является non-idempotent & non-safe - внутри может быть что угодно - как набор совершенно безобидных GET запросов, так и действительно non-idempotent POST запросы, а может быть и вовсе некоторая смесь из них. Только клиент и сервет знают, что же там такое внутри. HTTP метод перестал быть понятным для всех транзитных серверов, таких как HTTP прокси и кеши
  • В зависимости от набора запросов в пакете, сервер может создать новые ресурс(ы), обновить или удалить старые, или просто вернуть запрошенный ресурс. Некоторые из этих запросов могли завершиться с ошибкой, а другие были успешными. Передать эту информацию обратно клиенту в HTTP header нелегко, значит она будет втиснута в body ответа. Значит response тоже перестал быть прозрачным для всех транзитных серверов

Ну вот и всё, что бы из REST сделать SOAP больше ничего не нужно. На самом деле, стало даже хуже, чем если бы SOAP использовалось с самого начала - транзитные сервера теперь не знают у каких request/response HTTP headers значат то, что написанно в спецификации, а у каких уже ничего не значат.

Существуют также и
Прочие недостатки пакетирования запросов

Каким бы образом это решение не было бы сделано, результат будет являться тунелированием HTTP протокола внутри HTTP протокола. Задумайтесь на секунду, что это значит.
  • Клиенты должны понимать все тонкости HTTP, и не только на этапе создания пакета запросов, но также они должны иметь обработчики ошибок, повторов и т.п. Они должны уметь обрабатывать все фокусы HTTP протокола - chunked и gzipped ответы. Перенаправления и HTTP headers
  • Транзитные сервера перестанут кешировать, исчезнет поддержка ETag, If-Modified-Since и т.п. А умные load-balancer-ы перестанут load balance-ить
  • Сломается “conversation pattern” если таковой будет подразумеваться конечным сервером.
  • Огромная дыра в security, привет системным администраторам
  • ~37% overhead в трафике из-за преобразования двоичных данных в текст, а также неизвестный CPU overhead на сервере и клиенте что бы эти данные кодировать-декодировать
  • Поддержка атомарности выполнения всего набора запросов
  • Определение порядка выполнения запросов в наборе

На самом деле, если заглянуть в спецификацию протокола HTTP 1.1 то можно увидеть, что существует «Идеальное» решение

продолжение см часть II “Идеальное” решение

оригинал: www.katkovonline.com

work

Previous post Next post
Up