REST или RPC: что лучше использовать?

    Команда Simple-Server
    03.06.2026
    17 мин

    Материал подготовлен командой Simple-Server для администраторов VPS и выделенных серверов. Команды и пути проверяйте на тестовой машине перед production.

    Кратко о задаче

    Идея запуска вычислений маломощным клиентом на высокопроизводительном сервере появилась очень давно. Первыми «поставщиками» и «потребителями» новой технологии стали базы данных (в то время их гордо величали банки данных и даже базы знаний). Технология RPC оказалась довольно гибкой и обладающей большим потенциалом. Большой вклад в формирование этой концепции внесли Sybase, Sun Microsystems, Microsoft и многие другие.

    Впоследствии, когда монолитные архитектурные решения стали уступать место многозвенным, RPC органичным образом вписались в новые концепции. Из RPC также выросло много разных промышленных стандартов и протоколов. разберём два архитектурных решения, которые используют технологию вызова удаленной процедуры, — это CORBA и веб-сервисы.

    CORBA — или Common Object Request Broker Architecture, обобщенная архитектура брокеров объектных запросов. Это, пожалуй, самая полная архитектурная спецификация для построения распределенных систем. Зародилась в 80-х годах XX века, наибольшее распространение получила в 90-х годах того же столетия. Самым большим преимуществом CORBA по сравнению с другими распределенными архитектурами стало то, что в сети запуска вычислений и обмена результатами могли присутствовать гетерогенные (или разнородные) элементы, которые реализовывали стандарты этой архитектурной спецификации. Стало возможным сочетать различные экосистемы: Java, C/C++ и даже Erlang.

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

    Вторым серьезным препятствием для использования CORBA является ее сетевой стек. Он работает поверх протокола TCP и довольно сложен, некоторые реализации CORBA используют стандартные порты TCP (определенные и зарезервированные для CORBA), а некоторые — произвольные, и это никак не регламентируется; всё это идет вразрез с политиками безопасности корпоративных сетей. Также это делает применение CORBA в Интернете весьма неудобным и даже невозможным.

    Рабочей лошадкой большинства информационных систем является протокол HTTP. Он использует два четко определённых TCP-порта: 80 и 443. CORBA в то же самое время требует 4 разных TCP-порта для своих протоколов, при этом каждый протокол имеет свои временные характеристики и особенности. Поэтому CORBA будет хороша там, где требуется интеграция в уже существующую архитектуру информационной системы, которая уже построена с применением CORBA. Разрабатывать же новую информационную систему с применением этого архитектурного решения скорее всего не следует, поскольку сегодня существуют более эффективные и простые механизмы.

    С учетом всех недостатков CORBA, в конце 1990-х годов был сформирован стандарт, который положил начало так называемым веб-сервисам (web services). В отличие от CORBA, веб-сервисы использовали уже существующий, очень надежный и простой протокол — HTTP и полностью опирались на его архитектурные соглашения. У каждого сервиса имелся свой уникальный адрес URL (universal resource locator) и набор методов, также базирующихся на соглашениях HTTP. В качестве «носителя» информации используются машинно- и архитектурно-независимые форматы, такие как XML или JSON. В частности, некоторые реализации веб-сервисов используют формат, который называется SOAP — (Simple Object Access Protocol), который базируется на XML. Новое решение было значительно удобнее тяжеловесной CORBA, использовало простой и надежный протокол HTTP и, по сути, не зависело от технологий, механизмов развертывания и аспектов масштабирования информационных систем.

    Однако, вскорости новая технология «обросла» стандартами, правилами, спецификациями и прочими необходимыми, но очень скучными атрибутами такого явления, как Enterprise. SOAP — это удачное решение потому, что XML, который лежит в его основе, — это управляемый, машинно-независимый, определяемый пользователем язык обмена. В XML уже имеется валидация, описание структур данных и многое другое. Но у XML есть и обратная, темная сторона. XML — это до предела перегруженный вспомогательными элементами язык. Это атрибуты, теги, пространства имен, разные скобки, кавычки и многое другое. Львиную долю в пакетах SOAP составляет эта служебная информация. В пересчете на миллионы миллионов вызовов мы можем получить очень серьезные накладные расходы на весь этот информационный шум. Помочь «горю» тут сложно, это связано с особенностями использования пространств имен XML и чрезвычайно насыщенной такими семантическими определениями спецификацией SOAP. Применение менее «шумных» форматов данных (например JSON, в спецификации JSON-RPC) сопряжено с другими рисками, такими как несогласованность описаний данных и отсутствие описания их структуры.

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

    Может показаться, что RPC — это устаревшая концепция, которой в новых реалиях лучше не пользоваться, во избежание разного рода проблем и неприятностей, связанных с ошибками проектирования. Однако мы неспроста затратили так много времени на рассказ о технологиях прошлого. Если взять всё самое лучшее от CORBA, обернуть это в современные архитектурные решения и, подобно веб-сервисам, запустить поверх надежных сетевых протоколов, то мы с вами получим… gRPC!

    gRPC — это открытый фреймворк, который придумали и реализовали в Google. Он действительно очень похож на CORBA, но в отличие от нее работает поверх стандартного протокола HTTP версии 2. Эта версия популярного транспорта в значительной степени переработана, расширена и улучшена (в сравнении с предыдущими версиями) и обеспечивает эффективную передачу сообщений с низкой задержкой. CORBA использует свой собственный язык описания интерфейсов IDL (Interface Definition Language). В gRPC для этих же целей применяется современный фреймворк Protocol Buffers. Подобно CORBA, среда gRPC — гетерогенная, она позволяет различным экосистемам эффективно взаимодействовать друг с другом. ProtoBuff использует собственный транспортный формат (сериализация и десериализация объектов), который намного компактнее JSON и XML, оставаясь при этом машинно-независимым форматом. Сегодня gRPC потихоньку вытеснил всё, что только можно, в сегменте внутреннего взаимодействия микросервисов и потихонечку начинает захватывать те области, где раньше царствовали WEB-сервисы и REST. Некоторые отважные разработчики пробуют интегрировать gRPC во frontend! Всё потому, что gRPC был очень удачно спроектирован, он надежен, быстр, позволяет строить информационные системы из гетерогенных узлов и компонентов, подобно владычице морей CORBA.

    Однако, предположим: мне не нужно взаимодействие разных экосистем, я программирую только лишь на Python/Golang/Java/(впишите свое) и хочу иметь в своем распоряжении средства для распределения вычислений. Следует ли мне использовать gRPC, который, к слову сказать, потребует определенное время на вхождение в технологию, или есть что-то такое, что выручит меня «сразу и недорого»?

    Нам повезло. Сегодня пакеты и сервисные библиотеки, которые предоставляют RPC, есть практически во всех языковых экосистемах, например:

    • Python — пакет xmlrpc
    • Go — пакет net/rpc
    • Java — java.rmi (Remote method invocation)
    • Haskell — WAI, xmlrpc, встроенные в OTP средства распределения вычислений и кластеризации
    • Javascript — JSON-RPC

    Каждый из вышеупомянутых пакетов внутри языковых экосистем позволит вам связывать компоненты между собой.

    Проиллюстрируем это кодом, возьмем простой пример из документации модуля xmlrpc, стандартной библиотеки языка Python.

    from xmlrpc.server import SimpleXMLRPCServer def is_even(n): return n % 2 == 0 server = SimpleXMLRPCServer(("localhost", 8000)) print("Listening on port 8000...") server.register_function(is_even, "is_even") server.serve_forever() import xmlrpc.client with xmlrpc.client.ServerProxy("http://localhost:8000/") as proxy: print("3 is even: %s" % str(proxy.is_even(3))) print("100 is even: %s" % str(proxy.is_even(100)))

    Как мы видим, на стороне клиента всё выглядит очень наглядно и просто, словно функция is_even является частью кода самого клиента. На стороне сервера всё тоже довольно просто и понятно: мы определяем функцию, затем регистрируем ее в контексте серверного процесса, отвечающего за RPC. При этом важно обратить внимание на то, что функция, которую мы «открываем» для доступа извне, — это обычная функция, написанная на языке программирования Python. Ее запросто можно использовать в коде на стороне сервера, локально, передавая ей параметры и получая значение, которая она возвращает. Концепция RPC очень проста, элегантна и гибка: для вызова функции «на стороне» нужно лишь сменить транспорт: с локальных вызовов внутри процесса, на некий сетевой протокол обмена и обеспечить двунаправленную трансляцию параметров и результатов.

    Что же не так с RPC и почему мы в итоге получили в свое распоряжение еще и REST? Первая и, пожалуй, самая серьезная причина — RPC обязательно должен иметь некий слой, который описывает характер данных, интерфейсы, функции и возвращаемые вызовы. В CORBA — это IDL, в gRPC — ProtoBuf. Малейшее изменение потребует синхронизации всей совокупности определений и интерфейсов. Второй момент, пожалуй, проистекает из самого понятия «функция» — это черный ящик, который получает на вход аргументы и возвращает некое значение. Функция никак себя не описывает и не характеризует, понять, что именно она делает, можно только вызвав ее и получив некий результат. Соответственно, как и было упомянуто выше, нужно некое описание, опираясь на которое можно определять характер и порядок вычислений.

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

    Термин REST был введен Роем Филдингом, одним из авторов HTTP, в 2000 году, в его диссертации «Архитектурные стили и дизайн сетевых программных архитектур». Он подвел теоретическую основу под способ взаимодействия клиентов и серверов в глобальной сети, абстрагировав его и назвав «передачей представительного состояния». Рой Филдинг выработал концепцию построения распределенных приложений, в которой каждый запрос (REST-запрос) от клиента к серверу уже содержит в себе исчерпывающую информацию о желаемом ответе сервера (желаемом представительном состоянии), и сервер не обязан сохранять информацию о состоянии клиента («клиентской сессии»).

    Как же это устроено? В REST API каждый сервис, каждая единица информации обозначается своим URL. Таким образом, получить данные можно просто обратившись по этому URL к серверу. URL в REST устроен следующим образом:

    • /object/ — адресует нас к списку объектов
    • /object/id — адресует нас к единственному объекту с указанным ID или возвращает ответ 404, если такой объект не найден

    Таким образом, уже сам характер задания URL представляет нам характер ответа сервера: в первом случае — список объектов, во втором — единичный объект.

    Но это далеко не всё. REST, как было упомянуто выше, в качестве транспорта использует HTTP. А в HTTP одним из ключевых параметров, определяющих характер возвращаемых сервером данных является метод.

    С использованием HTTP-методов мы можем определить еще один ряд самоописываемых состояний:

    • GET /object/ — возвращает список объектов
    • GET /object/id — возвращает объект с указанным ID или 404
    • POST /object/ — создает новый объект или возвращает ошибку (чаще всего ошибку с кодом 400 или иную)
    • PUT /object/id — «редактирует» объект с указанным ID или возвращает ошибки
    • DELETE /object/id — удаляет объект с указанным ID или возвращает ошибки

    Некоторые серверы игнорируют семантику методов PUT и DELETE, в этом случае используется метод POST /object/id с телом запроса (данные объекта) для редактирования или тот же самый POST-запрос с пустым телом для удаления объекта.

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

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

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

    Кратко перечислим каждое из них.

    1. Архитектура сетей REST должна базироваться на модели «клиент-сервер». Отделение потребности интерфейса клиента от потребностей сервера повышает переносимость кода клиентского интерфейса, а упрощение серверной части улучшает масштабируемость.

    2. Отсутствие состояния. Сервер не должен хранить никакой специальной информации о клиенте в промежутках между вызовами. Традиционные для WEB сессии здесь неприемлемы. Всю необходимую информацию о состоянии клиента сервер должен получать из запроса.

    3. Кеширование. Результаты ответа сервера могут быть закешированы. Это позволит повысить производительность системы. Сервер должен заботиться о том, чтобы клиент получал актуальную информацию, если применяется кеширование.

    4. Единообразие интерфейса. Это касается единого способа записи URL объектов, который уже рассмотрен, и семантики HTTP-методов. Также это предполагает, что в качестве транспортного формата данных используется такой формат, который идентично транслируется и сервером и клиентом. Обычно это JSON, но возможны комбинированные варианты, когда используется JSON и CBOR (характер данных описывается в заголовке Content-type).

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

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

    Отсутствие состояния. Сервер не должен хранить никакой специальной информации о клиенте в промежутках между вызовами. Традиционные для WEB сессии здесь неприемлемы. Всю необходимую информацию о состоянии клиента сервер должен получать из запроса.

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

    Единообразие интерфейса. Это касается единого способа записи URL объектов, который уже рассмотрен, и семантики HTTP-методов. Также это предполагает, что в качестве транспортного формата данных используется такой формат, который идентично транслируется и сервером и клиентом. Обычно это JSON, но возможны комбинированные варианты, когда используется JSON и CBOR (характер данных описывается в заголовке Content-type).

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

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

    Один из самых популярных паттернов, который реализуется при помощи REST, — это CRUD. Этот акроним образуется по первым буквам от названия операций Create, Read, Update и Delete. Четыре базовых операции, которых достаточно для работы с любой сущностью данных. Более сложные операции, так называемые use cases (сценарии использования) могут использовать CRUD REST API для доступа к сущностям данных. Use Cases также могут следовать предписаниям и ограничениям REST; в таком случае мы называем нашу информационную систему RESTful. В такой системе везде используются соглашения REST и расширяется такая система также с применением вышеупомянутых соглашений. Это очень прагматичный и в то же время очень гибкий подход: единая архитектура уменьшает сложность системы, а с уменьшением сложности системы уменьшается процент ошибок.

    Концепция REST API настолько популярна, что есть практически в каждой языковой экосистеме. REST включен в Django и Laravel. В Go можно использовать пакет Gin Gonic или собрать свою RESTful-систему, применяя только лишь пакеты стандартной библиотеки. Для Erlang можно использовать библиотеку erf, а в Elixir REST API уже встроен в фреймворк Phoenix. REST, будучи архитектурой, не накладывает никаких ограничений на языковые среды, фреймворки и прочее — эта архитектура декларирует сервисам: просто «разговаривайте» на REST и всё будет замечательно.

    REST или RPC — «Одно Кольцо, чтобы повелевать всеми»? REST vs RPC – «Скорпион vs Саб-зиро»? Попробуем дать ответ на вопрос, который мы задали в самом начале. Как вы уже поняли из этой весьма обширной статьи, каждый подход обладает своими явными преимуществами и совершенно конкретными недостатками. В данном вопросе всё же хороша золотая середина. Для ответственных сервисов, которые обрабатывают огромные массивы данных, в первую очередь важна стабильность. Как в коде — ошибки в определениях данных тут просто исключены, так и в инфраструктуре — чем быстрее отклик системы, тем лучше. Для таких участков безусловно более удобной будет концепция RPC в ее современной реализации — gRPC. Однако там, где у нас «живет» бизнес-логика и разные сложные процессы взаимодействия уровней информационной системы, жесткий и ограниченный в средствах выражения REST будет более предпочтительным. Разумно и гибко применяйте оба подхода, и ваша информационная система будет использовать выгоды каждой концепции (или архитектурного решения).


    Нужен сервер для практики? Арендуйте VPS/VDS в России — root-доступ, NVMe, DDoS-защита и поддержка 24/7.

    VPS для проекта

    VPS с root-доступом, NVMe и поддержкой 24/7 на Simple-Server.

    StarterVDS

    490₽

    в месяц

    1 ядро

    1 ГБ RAM

    20 ГБ NVMe

    • 1 IPv4
    • KVM
    • Root-доступ
    • Безлимитный трафик
    Заказать VPS
    Рекомендуем

    PerformanceVDS

    1190₽

    в месяц

    2 ядра

    4 ГБ RAM

    60 ГБ NVMe

    • 1 IPv4
    • KVM
    • Root-доступ
    • Базовая DDoS-защита
    Заказать VPS

    Нужна другая конфигурация или чистый VPS без панели?

    Все тарифы VPS

    Похожие статьи, которые могут быть вам интересны