Существует ли стандартный способ объединения нескольких вызовов API в один HTTP-запрос? - PullRequest
2 голосов
/ 19 февраля 2020

При разработке остальных API-интерфейсов время от времени возникают проблемы, связанные с пакетными операциями (например, удаление или обновление множества объектов одновременно), чтобы уменьшить накладные расходы на многие соединения tcp-клиентов. И в конкретной ситуации проблема обычно решается добавлением пользовательского метода API для операции специфицирования c (например, POST /files/batchDelete, которая принимает ids в теле запроса), которая не выглядит симпатично с точки зрения принципов проектирования остальных API, но делает работа.

Но для меня общее решение проблемы все же желательно. Недавно я нашел Google Cloud Storage JSON Документация по пакетированию API , которая для меня выглядит довольно общим решением. Я имею в виду, что подобный формат может использоваться для любого http API, а не только для облачного хранилища Google. Поэтому мой вопрос - знает ли кто-нибудь какой-нибудь общий стандарт (стандарт или черновик, руководство, усилия сообщества или около того), когда несколько вызовов API объединяются в один HTTP-запрос?

I ' Я осведомлен о возможностях http / 2, которые включают использование одного TCP-соединения для http-запросов, но мой вопрос адресован уровню приложения. Что, на мой взгляд, все еще имеет смысл, потому что, несмотря на способность использовать http / 2, принятие этого на уровне приложения кажется единственным способом гарантировать это для любого клиента, включая http / 1, который в настоящее время является наиболее используемой версией http.

Ответы [ 2 ]

1 голос
/ 19 февраля 2020

TL; DR

  • REST или HTTP идеально подходят для пакетных операций.
  • Обычно кэширование, которое является одним из ограничений REST, которое не является обязательным, но обязательным, предотвращает пакетную обработку в некоторой форме.
  • Может быть выгодно не предоставлять данные для обновления или удаления в пакетном режиме как собственные ресурсы, а как элементы данных в пределах одного ресурса, например, таблицу данных на странице HTML. Здесь обновление или удаление всех или части записей должно быть прямым.
  • Если система в целом интенсивна для записи, вероятно, лучше подумать о других решениях, таких как предоставление БД напрямую этим клиентам, чтобы избавить от дальнейшего уровня косвенности и сложности.
  • Использование кэширование может предотвратить большую нагрузку на сервер и даже избавить от ненужных соединений

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

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

Как упоминалось ранее, HTTP не идеален с точки зрения действий пакетной обработки. Конечно, запрос GET может получить несколько результатов, хотя в действительности вы получаете один ответ, содержащий ссылки на дополнительные ресурсы. Создание ресурсов, согласно спецификации HTTP , должно указываться заголовком Location, который указывает на вновь созданный ресурс. POST определяется как универсальный метод, который позволяет выполнять задачи в соответствии с семантикой c, определенной сервером. Таким образом, вы можете использовать его для создания нескольких ресурсов одновременно. Однако в HTTP spe c явно отсутствует поддержка указания одновременного создания нескольких ресурсов, поскольку заголовок Location может появляться только один раз для каждого ответа, а также определять в нем только один URI. Итак, как сервер может указать создание нескольких ресурсов для сервера?

Еще одно указание на то, что HTTP не идеален для пакетной обработки, заключается в том, что URI должен ссылаться на один ресурс. Этот ресурс может со временем меняться, хотя URI никогда не может указывать на несколько ресурсов одновременно. Сам URI более или менее используется в качестве ключа кешами, которые хранят кэшируемое представление ответа для этого URI. Поскольку URI может когда-либо ссылаться только на один единственный ресурс, кэш также будет всегда хранить представление только одного ресурса для этого URI. Кэш аннулирует сохраненное представление для URI, если с этим URI выполняется небезопасная операция. В случае операции DELETE, которая по своей природе небезопасна, представление для URI, над которым выполняется DELETE, будет удалено. Если вы теперь «перенаправили» операцию DELETE, чтобы удалить сразу несколько резервных ресурсов, как кэш должен это заметить? Он работает только по вызванному URI. Следовательно, даже когда вы удаляете несколько ресурсов в одном go через DELETE, кэш может по-прежнему обслуживать клиентов с устаревшей информацией, поскольку он просто еще не обращал внимания на удаление, а его значение свежести все равно будет указывать на fre sh - Достаточно государства. Если вы не отключите кеширование по умолчанию, которое каким-либо образом нарушает одно из ограничений REST или не сократит период времени, в течение которого представление считается достаточно большим sh, до очень низкого значения, клиенты, вероятно, будут получать устаревшую информацию. Конечно, вы могли бы выполнить небезопасную операцию с каждым из этих URI, а затем «очистить» кэш, хотя в этом случае вы могли бы вызвать операцию DELETE для каждого ресурса, для которого нужно было выполнить пакетное удаление, чтобы начать с него.

Это становится немного проще, хотя, если пакет данных, который вы хотите удалить, явно не захватывается через их собственные ресурсы, а представляет собой данные одного ресурса. Подумайте о таблице данных на веб-странице, где у вас есть определенные элементы формы, такие как флажок, который вы можете щелкнуть, чтобы пометить запись как кандидата на удаление, а затем после вызова кнопки отправки отправить соответствующие выбранные элементы на сервер, который выполняет удаление этих предметов. Здесь обновляется только состояние одного ресурса, и, таким образом, простая операция POST, PUT или даже PATCH может быть выполнена с этим URI ресурса. Это также хорошо согласуется с кэшированием, как было описано ранее, поскольку необходимо изменить только один ресурс, что при использовании небезопасных операций с этим URI автоматически приведет к аннулированию любого сохраненного представления для данного URI.

упомянутое выше использование элементов формы для маркировки определенных элементов для удаления зависит, однако, от выпущенного типа носителя. В случае HTML в разделе форм указываются доступные компоненты и их возможности . Доступность - это знание того, что вы можете и должны делать с определенными объектами. Т.е. кнопка или ссылка могут быть нажаты, текстовое поле может ожидать ввода цифр c или буквенно-цифрового ввода c, что в дальнейшем может быть ограничено по длине и так далее. Другие типы носителей, такие как hal-формы , halform или ion , пытаются предоставить представления форм и компоненты для записи на основе JSON, однако поддерживают для таких медиа-типов все еще довольно ограничен.

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

Запись Однако в интенсивных сценариях использования кеширование не может принести такой же пользы, как в случаях с интенсивным чтением, поскольку кэш-память часто становится недействительной, а фактический запрос передается на сервер для обработки. Если API более или менее используется для выполнения операций CRUD, как в действительности делают многие API-интерфейсы REST, сомнительно, что было бы предпочтительным предоставлять базу данных напрямую клиентам. Почти все современные поставщики баз данных поставляются со сложными опциями управления правами пользователей и позволяют создавать представления, которые могут быть доступны для определенных пользователей. "REST API" поверх этого в основном просто добавляет дополнительный уровень косвенности и сложности в таком случае. При непосредственном воздействии на БД выполнение пакетных обновлений или удалений вообще не должно быть проблемой, поскольку с помощью соответствующих языков запросов поддержка таких операций уже должна быть встроена в слой БД.

Что касается количества соединения, которые создают клиенты: HTTP с версии 1.0 позволяет повторно использовать соединения с помощью директивы заголовка Connection: keep-alive. В HTTP / 1.1 постоянные соединения используются по умолчанию, если явно не запрашивается закрытие через соответствующую директиву заголовка Connection: close. HTTP / 2 представил полнодуплексные соединения, которые позволяют много каналов и, следовательно, запрашивает повторное использование одних и тех же соединений одновременно. Это более или менее исправление для ограничения соединения, предложенного в RF C 2626 , которого многие веб-разработчики избегали, используя CDN и подобные вещи. В настоящее время большинство реализаций используют максимальный лимит в 100 каналов и, следовательно, одновременную загрузку через одно соединение. AFAIK.

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

0 голосов
/ 19 февраля 2020

уменьшить накладные расходы на многие соединения tcp-клиента

Если суть проблемы, самый простой способ решить эту проблему - перейти на HTTP / 2

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

В конечном итоге пакетирование нескольких операций в одном HTTP-запросе всегда является сетевым хаком.

HTTP / 2 широко доступен. Если HTTP / 1.1 по-прежнему является наиболее используемой версией (это может быть правдой, но разрыв сокращается), это больше связано с серверами, которые еще не настроены для него, а не с клиентами.

...