В статье на Хабре
Создание интерактивного приложения с использованием Yandex API Gateway и протокола WebSocket
Рассказываем об использовании сервиса Yandex API Gateway и технологии WebSockets для работы асинхронных веб-приложений.
Сейчас практически невозможно представить себе современные веб‑ или мобильные приложения без отзывчивого, динамичного и привлекательного пользовательского интерфейса, который реализован за счёт быстрой загрузки данных. Современные веб‑сервисы отправляют сразу на клиентскую сторону информацию, как только она изменится на сервере, и не требуют при этом постоянного обновления страницы, на которой находится пользователь. Этот подход широко распространён в приложениях для совместного редактирования текстов, чатах, а также в онлайн‑играх, системах для мониторинга событий и многом другом.
Есть разные способы отправки данных с сервера в браузер или мобильное приложение без клиентского запроса. Один из самых современных и распространённых — это использование протокола WebSocket. Не так давно мы запустили поддержку этого протокола в сервисе Yandex API Gateway.
Что такое сервис Yandex API Gateway
При разработке IT‑решений, ориентированных на быструю доставку ценности до потребителя (time-to-market), часто используют микросервисный подход. Архитектурный паттерн, который предоставляет веб‑ и мобильным приложениям единую точку входа в API и за которым скрываются внутренние микросервисы, называется API Gateway. Необходимость реализации такого паттерна в сценариях наших клиентов подтолкнула команду Yandex Cloud создать сервис с соответствующей функциональностью — Yandex API Gateway. И 29 сентября 2020 года сервис вышел в общий доступ.
Yandex API Gateway значительно расширяет возможности разработчиков сервисов:
-
упрощает создание, публикацию и обслуживание как серверных, так и бессерверных приложений;
-
служит «входной дверью» для веб-сайтов и мобильных приложений.
С помощью Yandex API Gateway приложения получают доступ к данным, бизнес‑логике или функциональности из внутренних сервисов: Yandex Cloud Functions, Yandex Serverless Containers, YDB и других.
Ещё Yandex API Gateway берёт на себя ряд служебных функций, серьёзно облегчая разработку. Например, вы можете подключить свой домен для обращения к API. В этом случае для установления TLS‑соединения будет использован сертификат, заведённый в сервисе Certificate Manager и подтверждающий владение доменом.
Для того чтобы создать API‑шлюз, достаточно описать его спецификацию в соответствии со стандартом OpenAPI 3.0. Спецификация представляет собой перечисление ресурсов (HTTP‑путей), предоставляемых вашим API, и операций (HTTP‑методов) работы с ними. Операции реализуются посредством подключения различных сервисов Yandex Cloud к API‑шлюзу. Примерами таких интеграций могут быть вызов функции Yandex Cloud Functions или получение файла из Object Storage. Мы запустили Yandex API Gateway с базовой функциональностью и постоянно расширяем как набор интеграций, так и возможности сервиса в целом.
Поддержка протокола WebSocket в Yandex API Gateway
Наша команда внимательно следит за предложениями от пользователей по улучшению сервиса Yandex API Gateway. Среди них выделялось одно. Пользователь предлагал добавить в Yandex API Gateway поддержку WebSocket. Это предложение стало темой оживлённой дискуссии внутри команды. Одни считали, что поддержка WebSocket будет востребована большинством клиентов, другие — что нет. В итоге победили первые, а само предложение в разделе Идеи набрало 177 голосов. Сначала мы реализовали прототип, а позже добавили полноценную поддержку WebSocket.
WebSocket — это двунаправленный полнодуплексный протокол интернет‑связи, который обеспечивает асинхронный обмен сообщениями по одному TCP‑соединению. WebSocket позволяет в режиме реального времени осуществлять передачу данных между сервером и клиентом без цикла запрос‑ответ.
Реализация на сервере асинхронного взаимодействия с клиентским приложением в целом, как и реализация поддержки протокола WebSocket в частности, — задачи не из простых. Для пользователей сервиса Yandex API Gateway мы постарались всё максимально упростить. Большинство разработчиков привыкло писать веб‑сервисы, работающие в режиме запрос‑ответ, как это предполагает HTTP‑протокол. Мы предоставили возможность интегрировать такие сервисы с API‑шлюзом. Являясь как бы прокси‑сервером, API‑шлюз берёт на себя всю работу по взаимодействию с клиентским приложением в соответствии с протоколом WebSocket, продолжая общаться с бэкендом синхронно по HTTP‑протоколу. Таким образом, вы сможете не только создавать новые интерактивные и динамичные serverless‑приложения, но и поддержать протокол WebSocket в уже написанных и работающих в продакшне веб‑сервисах или HTTP‑серверах.
Чтобы реализовать поддержку протокола WebSocket в сервисе Yandex API Gateway, мы расширили спецификацию OpenAPI 3.0 тремя операциями. Они соответствуют трём основным событиям, происходящим с веб‑сокетами: открытие соединения, отправка сообщения через веб‑сокет, закрытие соединения. На эти события или операции вы можете настроить вызов любой интеграции, предлагаемой сервисом Yandex API Gateway: вызов функции YC Function, вызов HTTP‑сервиса, отправка сообщения в очередь YMQ или поток данных YDS и т. д. Подробнее в документации →
Протокол WebSocket в действии
Вызов HTTP‑метода GET со специальными заголовками по URI‑адресу сигнализирует серверу, что клиент хочет установить соединение по протоколу WebSocket. При этом для URI‑адреса в спецификации API‑шлюза должна быть настроена операция открытия веб‑сокета. В случае успешного ответа от интеграции API‑шлюз отвечает клиенту кодом «101 Switching Protocol». После этого веб‑сокет считается открытым согласно протоколу. Иначе — возвращается ошибка, полученная от интеграции.
Для каждого нового веб‑сокета генерируется уникальный идентификатор соединения. Он возвращается клиенту в заголовке. Вы можете использовать идентификатор для отслеживания состояния и управления соединением. Для этого мы предоставили вам удобный API (REST, GRPC, YC CLI). API содержит следующие методы: отправки данных на клиентскую сторону, закрытия соединения и получения состояния соединения. Вам достаточно сохранить идентификатор где‑нибудь у себя на сервере, например в базе данных Yandex Managed Service for YDB.
Как только соединение установлено, клиент и сервер могут отправлять сообщения туда и обратно. Повторно устанавливать соединение не нужно. При этом в нашей реализации WebSocket мы поддержали передачу как текстового, так и бинарного формата данных. Но нужно учитывать, что размер передаваемого сообщения ограничен. Подробнее в документации →
Соединения, которые долго висят или через которые не передаются данные, закрываются API‑шлюзом. Однако протокол WebSocket включает в себя «механизм пинг‑понга»: он позволяет клиенту и серверу подтвердить, что их соединение всё ещё работает и закрывать его не нужно.
На первый взгляд подход с использованием WebSocket кажется сложным. Но в действительности всё логично и удобно. Хотите в этом убедиться?
Чтобы вы могли как следует разобраться с работой поддержки WebSocket в сервисе Yandex API Gateway, наш коллега разработал интерактивное приложение
В этой статье мы расскажем: