# Сравнительная таблица

<table data-full-width="true"><thead><tr><th width="172"></th><th width="244">SOAP</th><th width="266">REST</th><th>gRPC</th></tr></thead><tbody><tr><td><strong>Протокол</strong></td><td>HTTP1.1.</td><td>HTTP1.1.</td><td>HTTP2 (работает в двух направлениях и за счет этого быстрее HTTP1.1)</td></tr><tr><td><strong>Подход</strong></td><td>сервисно-ориентированный дизайн. Клиент запрашивает у сервера услугу или функцию, которая может затрагивать ресурсы сервера</td><td>объектно-ориентированный дизайн. Клиент запрашивает у сервера создание, совместное использование или модификацию ресурсов</td><td>сервисно-ориентированный дизайн. Клиент запрашивает у сервера услугу или функцию, которая может затрагивать ресурсы сервера</td></tr><tr><td>                              </td><td>                                                    </td><td>                                                          </td><td>                                                                               </td></tr><tr><td><strong>Формат передаваемых данных</strong></td><td><p>Запрос: XML</p><p>Ответ: XML</p></td><td><p>Запрос: преимущественно JSON (реже XML)</p><p>Ответ: JSON со всеми данными, найденными на сервере по этой конечной точке</p></td><td><p>Запрос: бинарный файл — protobuf.</p><p>Ответ: бинарный файл — protobuf.</p></td></tr><tr><td><strong>Контракт</strong></td><td>обязательны WSDL-схемы</td><td>необязательно OpenAPI (Swagger), эндпоинты могут быть не задокументированы</td><td>обязательно пишется по стандарту Protocol Buffers, компилируется внутренним компилятором protoc, который генерирует необходимый исходный код классов из определений в proto-файле</td></tr><tr><td><strong>Документирование</strong></td><td>WSDL-схемы сложно писать и поддерживать</td><td>в JSON нужно задокументировать содержащиеся в нем поля и их типы. Часто информация может быть неточной, неполной или устаревшей.</td><td>четко определенная и самодокументируемая схема. API на Protobuf генерирует код, код не будет рассинхронизирован с документацией. При генерации кода из Protobuf проходит базовая проверка — сгенерированный код не принимает поля неправильного типа.</td></tr><tr><td><strong>Вес</strong></td><td>XML весит больше аналогичных JSON и base64 и в основном применяется в legacy-системах, которые были разработаны в конце 1990-х — начале 2000-х.</td><td>JSON меньше XML, но больше protobuf</td><td>меньше JSON</td></tr><tr><td><strong>Производительность</strong></td><td>Средняя, данные требуют дополнительной сериализации (парсинга)</td><td>Средняя, данные требуют дополнительной сериализации (парсинга)</td><td>Высокая, данные изначально сериализованы</td></tr><tr><td>                              </td><td>                                                    </td><td>                                                          </td><td>                                                                               </td></tr><tr><td><strong>Связь с сервером</strong></td><td></td><td>1—1</td><td>1—1, 1—N, N—N</td></tr><tr><td><strong>Скорость обмена</strong></td><td></td><td>Средняя, обмен однонаправленный (запрос-ответ)</td><td>Высокая, обмен двунаправленный или стриминговый</td></tr><tr><td><strong>Как передает данные</strong></td><td>использует только HTTP-POST-запросы</td><td><p>создает <strong>разовое</strong> соединение между двумя точками: создал соединение, отправил и закрыл. Клиент шлет в API сообщения и сразу получает ответ или ждет формирования ответа. Клиенту и серверу не нужно знать о внутренних данных. </p><p>Использует четыре основных метода HTTP: GET, POST, PUT, DELETE.</p></td><td><p>создает <strong>постоянное</strong> соединение — сокет — между двумя точками, по которому передает бинарный файл и вызывает удаленно функцию, передавая в нее параметры. Шлет сообщения в обе стороны: gRPC обеспечивает двунаправленную потоковую передачу данных — и клиент, и сервер могут одновременно посылать и получать несколько запросов и ответов в рамках одного соединения. REST так не умеет. </p><p>Использует только HTTP-POST-запросы.</p></td></tr><tr><td><strong>Число конечных точек (точек входа в приложение)</strong></td><td>1</td><td>без ограничений</td><td>1</td></tr><tr><td>                              </td><td>                                                    </td><td>                                                          </td><td>                                                                               </td></tr><tr><td><strong>Работа в вебе</strong></td><td>без допусилий</td><td>без допусилий</td><td><p></p><p>с дополнительными усилиями: </p><ul><li>gRPC работает на HTTP2 и передает бинарный файл, а JS в браузере работает на HTTP1 и взаимодействует только с текстовыми файлами. Поэтому существует gRPC-WEB, который может положить base64 в тело текстового сообщения, а затем JS отдельной библиотекой переводит base64 в JSON. gRPC-WEB —  отдельный от gRPC протокол, существует только в браузере и действует как уровень перевода между gRPC и приложением в браузере.</li><li>Фронтовый кодген не знает, где поле обязательное, а где нет. Все не базовые типы генерируются как optional.</li><li>Стримы для фронта стали доступны не так давно. Раньше для отправки файла писали rest-точку.</li></ul></td></tr><tr><td><strong>Для какой архитектуры</strong></td><td>сложная архитектура, выходящая за рамки CRUD. SOAP используют многие банки.</td><td>преимущественно CRUD. Самая популярная архитектура API для веб-сервисов и микросервисных архитектур.</td><td>преимущественно CRUD</td></tr><tr><td><strong>Мультиязыковая поддержка</strong></td><td>Не зависит от языка</td><td>Средняя, требуются сторонние сервисы для мультиязыковых систем</td><td>Высокая, встроенная автоматическая генерация кода для популярных языковых сред</td></tr><tr><td><strong>Достоинства</strong></td><td><ul><li>Не зависит от языка.</li><li>Встроенная обработка ошибок.</li><li>Встроенный протокол безопасности.</li><li>Самодокументируемый.</li></ul></td><td><p></p><ul><li>Клиент отделен от сервера.</li><li>Нет длительного соединения с отслеживанием состояния → экономия ресурсов.</li><li>Масштабируемость.</li><li>Простой в использовании и понимании, большое комьюнити.</li><li>Есть стандартный список кодов ошибок, но все пользуются им по-своему.</li><li>Можно внедрять в самых разных форматах без стандартного программного обеспечения.</li><li>Кэширование на уровне HTTP без дополнительных модулей.</li></ul></td><td><p></p><ul><li>Высокая производительность и низкая нагрузка на сеть.</li><li>Держит соединение, не надо тратить время на подключение.</li><li>Можно поставить таймаут клиента и тем самым экономить ресурсы.</li><li>Строгая спецификация типов данных. Под каждое поле выделяет набор битов по порядку.</li><li>Стандартизация кодов ошибок, зашитая в protobuf.</li><li>Сам генерирует исходный код по proto.</li><li>Самодокументируемый.</li><li>Не зависит от языка, контракт везде одинаковый.</li><li>Можно использовать для управления контейнерами в k8s и системами хранения данных.</li></ul></td></tr><tr><td><strong>Недостатки</strong></td><td><p></p><ul><li>Тяжелый XML.</li><li>Сложный набор правил для описания контракта.</li><li>Долгое обновление сообщений — особенности схемы.</li><li>Постоянная необходимость в кодировании данных на сервере до передачи по каналам связи и их последующем декодировании на клиенте.</li></ul></td><td><p></p><ul><li>Избыточная нагрузка на сеть.</li><li>Избыточная или недостаточная выборка данных.</li><li>Нет документирования и стандартизации.</li><li>Нет стандарта использования кодов ответов, поэтому часто в успешных кодах могут передаваться ошибки.</li><li>Постоянная необходимость в кодировании данных на сервере перед передачей по каналам связи и последующем их декодировании на клиенте.</li></ul></td><td><p></p><ul><li>Не работает без gRPC-WEB в браузере.</li><li>Человек не прочитает сообщение без декодера.</li><li>Для работы нужно программное обеспечение gRPC как со стороны клиента, так и со стороны сервера.</li></ul></td></tr><tr><td><strong>Когда использовать</strong></td><td>финтех и другие долгие массивные проекты со сложной архитектурой, легаси с 90-00 хх гг. или исторически выбранный SOAP, от которого не отказаться. Для нового проекта, возможно, стоит присмотреться к альтернативам.</td><td>благодаря простой реализации и отображению структуры данных, удобству чтения с ним легко работать начинающим программистам.</td><td>разработан для того, чтобы дать разработчикам возможность создавать высокопроизводительные API для микросервисных архитектур в распределенных центрах обработки данных. В том числе для микросервисных архитектур на нескольких языках программирования, для которых API вряд ли будет меняться со временем. Также он хорошо подходит для внутренних систем, требующих потоковой передачи данных в реальном времени и загрузки больших объемов информации.</td></tr></tbody></table>

Источник: <https://habr.com/ru/companies/tinkoff/articles/780024/>
