Почему REST обычно используется вместо RPC-подобных механизмов в веб-приложениях?

18

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

Связь с сервером выглядит как простой вызов функции, но функция выполняется на сервере, а не на клиенте. На стороне сервера есть способ определить, какие функции может вызывать клиент. Детали того, как это переводится в http-запросы, полностью абстрагированы.

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

Вивьен
источник
5
Я бы предположил (но я не уверен на 100%, поэтому я просто оставлю это как комментарий и позволю кому-то, кто действительно знает их материал, опубликовать правильный ответ), что REST используется больше, чем RPC, потому что интерфейсы REST обычно проще реализовать и менее зависимы от конкретных базовых структур / технологий.
FrustratedWithFormsDesigner
11
У меня сложилось впечатление, что большинство потребителей REST больше заботятся о простом API http + json, чем о самом REST.
CodesInChaos
4
Потому что вся индустрия сошла с ума.
Майк Накис
Это может вас заинтересовать stackoverflow.com/q/15056878/5934037
Laiv
1
Спорные мнение: по большей части различия между REST и RPC в основном академический характер .
whatsisname

Ответы:

33

REST был разработан для Интернета, а Интернет был разработан для REST. Два просто подходят друг другу. В 2000 году докторская диссертация Роя Филдинга « Архитектурные стили» и «Проектирование сетевых программных архитектур» определила и ввела термин « REST» , и между сетью и REST существует существенное взаимодействие: Рой Филдинг работал над HTTP / 1.1, основным автором которого он является, и он использовал то, что узнал там, чтобы описать ОТДЫХ в своей диссертации.

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

Вот почему REST хорошо подходит для веб-сервисов и веб-приложений: потому что вы просто делаете те же самые вещи, которые уже были доказаны для работы в «человеческой» сети, и применяете их в «машинной» сети.

Большая проблема с RPC ( в зависимости от точной реализации) лежит в основном в Заблуждения распределенных вычислений , которые более подробно описаны в этом документе по Арнон Ротем-Гал-Оз :

  1. Сеть надежна
  2. Задержка равна нулю
  3. Пропускная способность бесконечна
  4. Сеть безопасна
  5. Топология не меняется
  6. Есть один администратор
  7. Транспортная стоимость равна нулю
  8. Сеть однородна

Это все предположения, которые обычно делают новички, когда начинают создавать распределенные системы. Конечно, все они ложные. И вам необходимо учитывать их все при создании распределенных систем.

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

  • местный звонок никогда не выходит из строя; подпрограммы , которые вы назвали , может потерпеть неудачу, но вызов сам никогда не делает - удаленный вызов может заблудиться в сети
  • местный звонок мгновенный; подпрограмма , что вы назвали , может работать в течение длительного времени (или даже навсегда , если он застревает в бесконечном цикле), но вызов сам по себе не имеет вообще никакого времени (ну, несколько инструкций процессора в лучшем случае , меньше , если вызов встроенный, но очень быстрый) - удаленный вызов может застрять в сети надолго
  • если подпрограмма возвращается нормально, результат всегда возвращается - при удаленном вызове результат может потеряться в сети
  • возвраты мгновенные - удаленные результаты могут путешествовать по сети в течение длительного времени
  • если я вызову подпрограмму один раз, она будет выполнена ровно один раз - удаленный вызов может потеряться в сети или дублироваться, поэтому удаленная подпрограмма может выполняться от 0 до любого числа раз
  • Я получаю только один результат - удаленный результат может быть потерян или дублирован, поэтому вы можете получить результат 0 или более раз.
  • если я вызываю подпрограмму дважды, я получаю два результата и получаю результат первого вызова перед результатом второго вызова - вы, вероятно, можете догадаться об этом сейчас: с помощью RPC вы можете не получить никаких результатов или только первый или может быть потеряно только второе, или второе перед первым, или первое, и вы получите второе дважды, или наоборот, и так далее ...
  • если я позвоню, aа затем bвернусь результат, aа затем результат b - это просто более общая версия предыдущего пункта, с помощью RPC вы можете получить любой из двух ответов 0 или более раз в любом порядке.

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

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

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

Сравните это с подходом , как Erlang, который делает работу: в Erlang, все сообщения посылов рассматриваются как удаленные, даже если они являются локальными. Это означает, что вы всегда готовы решить все вышеперечисленные проблемы (и многие другие). Однако для локальных процессов это создает некоторые накладные расходы. Чтобы помочь с этим, есть много инструментов, структур, библиотек, шаблонов и идиом для работы с ошибками и надзора.

Вы не описали, в частности, как работает ваш RPC-фреймворк и какой язык или библиотеки вы используете, но у меня есть сильное подозрение, что он относится к предыдущему типу «притвориться, что сеть не существует». Те просто не работают. Это нормально, чтобы удалить различие между локальными и удаленными вызовами, рассматривая все как удаленный вызов. Делая это наоборот, абстрагируешься слишком много: сеть - это часть твоей системы, если ты ее абстрагируешь, то абстрагируешься от того, о чем тебе действительно нужно знать.

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

Йорг Миттаг
источник
Разве стандартизация также не является проблемой (учитывая, что между HTTP и RPC нет сопоставления 1: 1)?
Джимми Т.
Ну, есть модели Actor Model, которые решают все эти проблемы.
Роберт Харви
Конечно, все, что нужно, - это какой-то энтузиаст, создавший уровень абстракции через интерфейс REST, и он быстро становится неотличимым от интерфейса RPC.
whatsisname
1
Еще одна ошибка распределенных вычислений: клиенты и серверы обновляются одновременно.
Джек,
@Jack: Это связано с ошибкой «Есть только один администратор». Это упоминается в официальном документе:…
Йорг Миттаг
5

В комментариях уже есть несколько хороших идей, которые я повторю здесь:

  1. RPC обычно зависит от технологии.
  2. Больше всего разработчиков интересует JSON, а не REST.

У JSON есть очень хорошие качества. Это просто, легко для человека, легко для компьютера, чтобы разобрать, и Javascript мгновенно распознает его изначально (это, вы знаете, нотация объектов Javascript ).

Если вы готовы отказаться от ограничений, таких как REST, вы можете делать с JSON практически все, что захотите, включая вызовы удаленных процедур. Все, что вам нужно сделать, это установить подходящий протокол. На самом деле такой протокол уже существует: JSON-RPC.

--> {"jsonrpc": "2.0", "method": "subtract", "params": [42, 23], "id": 1}
<-- {"jsonrpc": "2.0", "result": 19, "id": 1}
Роберт Харви
источник
-1

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

Камаль Хоссейн
источник