Обзор
Последнее обновление: февраль 2022 г.
Оригинал статьи о Сообществе разработчиков Refinitiv доступен здесь.
Веб-API RESTful (или просто REST API) сегодня являются основным стандартом индустрии программного обеспечения. API-интерфейсы свободно основаны на методах HTTP, к которым легко получить доступ с любого языка программирования, платформы, устройства и ОС. Облачные технологии и интернет-сервисы используют API-интерфейсы REST, чтобы приложение или служба могли подключаться к ним.
Однако, если вы являетесь веб-разработчиком, ваше клиентское приложение JavaScript не может напрямую подключаться к этим веб-службам RESTful из-за политики Same-origin. Все веб-браузеры применяют эту политику, чтобы предотвратить доступ браузеров к различным ресурсам домена/сервера. И, конечно же, ваш веб-сервер/домен веб-приложения всегда отличается от облачных сервисов, потому что они размещены на разных сайтах.
В этом примере проекта показано, как использовать обратный прокси-сервер, чтобы JavaScript в веб-браузере мог подключаться и использовать данные из службы RESTful, используя API Refinitiv Data Platform (RDP) в качестве примера REST API. Он использует модуль http-proxy и веб-фреймворк Express.js для функций веб-сервера и обратного прокси.
Примечание. Обратите внимание, что эта статья и примеры проектов предназначены только для целей разработки и POC. Этот вид реализации обратного прокси-сервера не рекомендуется для использования в производственной среде. Вы можете использовать сервер де-факто, такой как Nginx, для обратного прокси-сервера в вашей среде. В качестве альтернативы вы можете использовать Неявный грант RDP.en/api-catalog/refinitiv-data-platform/refinitiv-data-platform-apis/tutorials#authorization-for-browser-based-applications).
Зачем нам нужен обратный прокси?
Вернемся к первому вопросу: почему веб-браузеры не могут напрямую подключаться к RDP API? Как правило, веб-браузеры не разрешают вашему коду JavaScript вызывать сторонний веб-API, который находится на другом сервере (междоменный запрос). Браузеры разрешают только HTTP-ответ с заголовком Control-Allow-Origin (Cross-Origin Resource Sharing — CORS) со значением * или доменом вашего клиента. В качестве примера см. следующий сценарий.
В приведенном выше сценарии браузер открывает файл из локального местоположения файла file:///C:/drive_d/Project/Code/RDP_HTTP_PROXY/public/index.html
.
- Это означает, что домен этой сети находится на локальной машине (
file:///C
). - Приложение JavaScript отправляет сообщение запроса аутентификации в службу аутентификации RDP по URL-адресу
https://api.refinitiv.com
, который находится в другом домене. - Браузер блокирует запрос и выдает сообщение об ошибке CORS (Cross-Origin Resource Sharing).
- JavaScript получает сообщение об ошибке, а не токены RDP, поэтому он не может продолжать запрашивать данные с другими конечными точками RDP.
Поведение этого браузера можно проиллюстрировать следующей диаграммой.
Сторонние веб-API не обязательно должны быть конкретно RDP, это может быть ваша микрослужба, которая также размещена в другом домене. Итак, как мы можем справиться с этим? Вы можете создать шлюз API в качестве обратного прокси-сервера для перенаправления трафика на различные службы в соответствии с URL-адресом запроса.
По состоянию на февраль 2022 г. Некоторые сервисы RDP, такие как экологические, социальные и управленческие (ESG), новости, символы и т. д., поддерживают междоменное управление-разрешение-происхождение. Вы можете вызывать их непосредственно из веб-браузеров (если у вас уже есть токен доступа). Однако я собираюсь применить эти вызовы к прокси-серверу для упрощения управления и предотвращения любых будущих изменений.
Вы можете использовать другие библиотеки/инструменты для работы с прокси, например, проект Refinitiv-API-Samples/Example.RDPAPI.TypeScript.AngularESGWebapp, который использует платформу Angular в качестве прокси на стороне клиента.
Примечание. Позвольте мне еще раз напомнить вам, что эта реализация прокси-сервера предназначена только для целей разработки и POC. Не рекомендуется для использования в производстве. Вы можете использовать сервер де-факто, такой как Nginx, для обратного прокси-сервера в вашей среде. В качестве альтернативы вы можете использовать Неявный грант RDP.
Что такое API Refinitiv Data Platform (RDP)?
API Refinitiv Data Platform (RDP) предоставляют разработчикам различные данные и контент Refinitiv через простой в использовании веб-API.
API-интерфейсы RDP предоставляют разработчикам беспрепятственный и целостный доступ ко всему контенту Refinitiv, такому как история ценообразования, экологические, социальные и управленческие (ESG), новости, исследования и т. д., а также к их контенту, обогащая, интегрируя и распространяя данные через единый интерфейс. , доставлены туда, куда им это нужно. Механизмы доставки RDP API следующие:
- Запрос — ответ: веб-служба RESTful (HTTP GET, POST, PUT или DELETE)
- Оповещение: доставка — это механизм получения асинхронных обновлений (предупреждений) для подписки.
- Пакеты: доставляйте существенные полезные данные, такие как данные о ценах на конец дня для всего места проведения.
- Потоковая передача: доставка сообщений в режиме реального времени.
Этот пример проекта фокусируется только на методе доставки веб-сервиса Request-Response: RESTful.
Express.js с HTTP-прокси
Начнем с серверного приложения. В этом примере используется Node.js с фреймворками Express.js.
Настроить веб-сервер Express.js
Во-первых, создайте веб-сервер с Express.js для обслуживания статического содержимого (доступно в папке с именем public
). Файл сервера называется server.js
.
Настройте HTTP-прокси для обратного прокси-сервера аутентификации RDP
Затем создайте прокси-объект как объект apiProxy
с модулем http-proxy в файле server.js
.
Затем примените URL RDP API https://api.refinitiv.com
к маршруту apiProxy и Express.js /auth/oauth2/<version>/*
.
Приведенный выше код обрабатывает HTTP Post для маршрута операции /auth/oauth2/<version>/*
, а затем использует функцию http-proxy web()
для перенаправления входящего сообщения HTTP-запроса (тело запроса, заголовки запроса, аутентификация запроса и т. д.) на целевой сервер RDP API следующим образом:
- Перенаправить входящее сообщение запроса HTTP Post для
/auth/oauth2/v1/token
на конечную точку RDPhttps://api.refinitiv.com/auth/oauth2/v1/token
. - Перенаправить входящее сообщение запроса HTTP Post для
/auth/oauth2/v1/revoke
на конечную точку RDPhttps://api.refinitiv.com/auth/oauth2/v1/revoke
.
Обратите внимание, что я храню все версии конечных точек RDP в переменной Environment, поэтому, если есть какое-либо обновление версии, мне не нужно менять исходный код.
Пример переменных среды (или файла .env
):
RDP_BASE_URL=https://api.refinitiv.com RDP_AUTH_VERSION=v1 RDP_ESG_VERSION=v2 RDP_SYMBOLOGY_VERSION=v1 RDP_NEWS_VERSION=v1
Настройте обратный прокси-сервер для других конечных точек
Затем добавьте дополнительные обработчики маршрутов HTTP для служб ESG, News и Symbology.
Приведенный выше код обрабатывает операции HTTP для сообщений запроса RDP, а затем перенаправляет входящее сообщение запроса HTTP (тело запроса, заголовки запроса, запрос аутентификации и т. д.) на целевой сервер RDP API с функцией http-proxy web()
следующим образом:
- Перенаправить входящее сообщение запроса HTTP Post для
/discovery/symbology/v1/lookup
на конечную точку RDPhttps://api.refinitiv.com/discovery/symbology/v1/lookup
. - Перенаправить входящее сообщение запроса HTTP Get для
/data/environmental-social-governance/v2/views/*
на конечную точку RDPhttps://api.refinitiv.com/data/environmental-social-governance/v2/views/*
. - Перенаправить входящее сообщение запроса HTTP Get для
/data/news/v1/headlines/
на конечную точку RDPhttps://api.refinitiv.com/data/news/v1/headlines/
.
Теперь приложение веб-сервера server.js готово обслуживать статическое содержимое и выполняет обратный прокси операций RDP.
Клиентский JavaScript
Переходим к клиентскому JavaScript в веб-браузерах. В этом примере используется ванильный JavaScript (также известный как чистый JavaScript), поэтому ту же концепцию можно применить и к любой среде JavaScript. Файл приложения JavaScript на стороне клиента называется app.js
.
Авторизация токенов RDP
Проверка прав RDP API основана на спецификации OAuth 2.0. Первым шагом рабочего процесса приложения является получение токена, который позволит получить доступ к защищенному ресурсу, то есть API REST данных. Для API требуются следующие учетные данные для доступа:
- Имя пользователя: имя пользователя.
- Пароль: пароль, связанный с именем пользователя.
- Идентификатор клиента: также известен как
AppKey
и генерируется с помощью генератора ключей приложения. Этот уникальный идентификатор определяется для пользователя или приложения и считается конфиденциальным (не передается пользователям). Параметр client_id может быть передан в теле запроса или как заголовок запроса «Авторизация», который закодирован как base64.
Приложение должно отправить сообщение HTTP Post с учетными данными для доступа к конечной точке службы аутентификации RDP. Однако служба проверки подлинности RDP не поддерживает CORS, поэтому клиентское приложение вместо этого отправляет сообщение запроса проверки подлинности на прокси-сервер (server.js) /auth/oauth2/v1/token
конечной точки. server.js просто перенаправляет наше сообщение HTTP Post на сервер RDP и перенаправляет ответное сообщение RDP обратно на app.js.
Функция authenRDP()
использует Fetch API для отправки сообщений HTTP-запросов как для первого входа в систему (authReq['grant_type'] = 'password'
), так и для сценария обновления токена (authReq['grant_type'] = 'refresh_token'
) в службу аутентификации RDP (через server.js).
После успешной аутентификации функция получает ответное сообщение службы аутентификации RDP (через server.js) и сохраняет следующую информацию о токене RDP в переменных на стороне клиента.
- access_token: токен, используемый для вызова вызовов API данных REST, как описано выше. Приложение должно сохранить эти учетные данные для дальнейших запросов RDP/Refinitiv Real-Time — Optimized.
- refresh_token: токен обновления, который будет использоваться для получения обновленного токена доступа до истечения срока действия. Приложение должно сохранить эти учетные данные для обновления токена доступа.
- expires_in: время действия токена доступа в секундах.
Полную информацию и объяснение рабочего процесса приложения процесса аутентификации RDP см. в следующих руководствах по RDP APIS:
Обновление токенов RDP
Перед истечением срока действия сеанса приложению необходимо отправить сообщение запроса Refresh Grant, чтобы получить новый маркер доступа. Давайте изменим функцию authenRDP()
, чтобы она также поддерживала запрос Refresh Grant.
Теперь app.js поддерживает сценарии предоставления пароля и предоставления обновления для RDP API с помощью одной функции authenRDP()
. Это относится к части аутентификации клиентского приложения app.js.
Запрос данных RDP API
Это подводит нас к запросу данных RDP API. Все последующие вызовы REST API используют токен доступа через заголовок сообщения HTTP-запроса Авторизация, как показано ниже, для получения данных.
- Заголовок:
- Авторизация =
Bearer <RDP Access Token>
Обратите внимание на пробел между значениями Bearer
и RDP Access Token
.
Затем приложение создает сообщение запроса в формате сообщения JSON или параметр запроса URL на основе интересующей службы и отправляет его как сообщение запроса HTTP в конечную точку службы. Разработчики могут получить API-интерфейсы RDP, конечную точку службы, операции HTTP и параметры на странице API Playground Refinitiv Data Platform, к которой разработчики интерактивного сайта документации могут получить доступ, если у них есть действующая учетная запись Refinitiv Data Platform.
Этот проект демонстрирует следующие службы RDP:
- ESG Service
/views/basic
операция, предоставляющая базовый обзор 6 общих данных ESG для потребителей. - Служба новостей
/headlines
операция. - Конечная точка службы обнаружения
/lookup
, которая перемещается между идентификаторами или сопоставляет идентификаторы с идентификаторами PermID.
Все сообщения HTTP-запросов от app.js на стороне клиента отправляются на server.js. Модуль http-proxy перенаправляет сообщение запроса в службу RDP и пересылает ответное сообщение от RDP на сторону клиента.
Примечание. По состоянию на февраль 2022 года текущая версия службы RDP ESG — v2.
Функция getSymbology()
поддерживает два сценария: преобразование кода RIC в коды ISIN и биржевых тикеров и преобразование кода RIC в код PermID. Разница заключается в теле запроса JSON. Пользователи могут нажимать кнопки, чтобы выбрать сценарий для выполнения.
В приведенном ниже коде показано, как преобразовать код RIC в коды ISIN и биржевых тикеров.
Функция getSymbology()
поддерживает два сценария: преобразование кода RIC в коды ISIN и биржевых тикеров и преобразование кода RIC в код PermID. Разница заключается в теле запроса JSON. Пользователи могут нажимать кнопки, чтобы выбрать сценарий для выполнения.
В приведенном ниже коде показано, как преобразовать код RIC в коды ISIN и биржевых тикеров.
В приведенном ниже коде показано, как преобразовать код RIC в код PermID.
Это охватывает базовый рабочий процесс HTTP-операций кода app.js на стороне клиента. Пример веб-приложения теперь может войти в RDP, получить токен доступа и запросить данные через http-прокси.
Предпосылка
Для этого демонстрационного проекта требуется следующее программное обеспечение зависимостей.
- Учетные данные RDP-доступа.
- Среда выполнения JavaScript Node.js.
- Интернет-соединение.
- Docker Desktop/Engine, если вы хотите работать с Docker.
Пожалуйста, свяжитесь с вашим представителем Refinitiv, чтобы помочь вам получить доступ к учетной записи и услугам RDP. Дополнительные сведения об учетных данных для доступа по протоколу RDP, настроенных при аренде, см. в разделе Начало работы для идентификатора пользователя статьи Начало работы с Refinitiv Data Platform.
Как запустить пример с Docker
Во-первых, перейдите в папку проекта и создайте имя файла .env со следующим содержимым.
RDP_BASE_URL=https://api.refinitiv.com RDP_AUTH_VERSION=v1 RDP_ESG_VERSION=v2 RDP_SYMBOLOGY_VERSION=v1 RDP_NEWS_VERSION=v1
Затем запустите команду $> docker build -t <project tag name> .
в консоли, чтобы создать образ из Dockerfile.
$> docker build -t rdp-http-proxy .
После успешной сборки вы можете создать и запустить контейнер с помощью следующей команды
$> docker run --name rdp-http-proxy -it --env-file .env -p 8080:8080 rdp-http-proxy
Откройте URL-адрес http://localhost:8080 в веб-браузере, чтобы запустить пример веб-приложения.
Вы можете нажать кнопки Ctrl+C
, чтобы выйти из серверного приложения, затем остановить и удалить контейнер с помощью следующих команд.
$> docker stop rdp-http-proxy $> docker rm rdp-http-proxy
Кроме того, вы можете настроить и запустить проект вручную, следуя инструкциям в GitHub.
Поиск неисправностей
Вопрос. Я дважды щелкаю файл index.html, чтобы открыть пример веб-приложения, ввожу свои учетные данные RDP и нажимаю кнопку аутентификации. На странице отображается сообщение об ошибке TypeError: Failed to fetch.
Ответ. Вы не можете запустить пример, просто дважды щелкнув файл index.html. Вам нужно запустить пример веб-сервера и открыть пример веб-приложения с URL-адресом http:localhost:8080 в веб-браузере.
Вопрос: я пытаюсь запустить веб-сервер с помощью команды npm start
, но он показывает сообщение об ошибке Ошибка: не удается найти модуль 'express'.
Ответ: вам необходимо установить зависимости проекта с помощью команды npm install
перед запуском команды npm start
.
Вопрос: у меня нет учетных данных RDP.
Ответ: обратитесь к представителю Refinitiv, чтобы получить доступ к учетной записи RDP и службам.
Вопрос. Я получил сообщение об ошибке {"error":"access_denied"}
, когда нажимаю кнопку аутентификации.
Ответ. Это сообщение об ошибке означает, что ваши учетные данные RDP не имеют разрешения на доступ к API. Пожалуйста, свяжитесь с представителем Refinitiv, чтобы подтвердить разрешение вашей учетной записи.
Вопрос: я получил {"error": "access_denied", "error_description": "Invalid username or password."}
, когда нажал кнопку аутентификации.
Ответ. Это сообщение об ошибке означает, что ваши учетные данные RDP недействительны. Пожалуйста, свяжитесь с вашим представителем Refinitiv, чтобы подтвердить свои учетные данные.
Вопрос. Я получил сообщение «ошибка 403», когда нажимаю кнопки запроса данных RDP.
Ответ: HTTP 403 (403 Forbidden) означает, что у вас нет разрешения на запрос данных. Пожалуйста, свяжитесь с представителем Refinitiv, чтобы подтвердить разрешение вашей учетной записи.
Заключение
С архитектурой разработки программного обеспечения приложение (или служба) больше не обращается только к серверам в своей серверной части. Ему необходимо подключаться к различным поставщикам услуг через Интернет, таким как облачное хранилище данных, веб-службы и т. д. Прокси-серверы и обратные прокси-серверы помогают приложению интегрироваться с различными службами и поставщиками данных.
В этом примере проекта показано, как интегрировать приложение веб-браузера в различные службы с обратным прокси-сервером. Клиентское приложение JavaScript может получать доступ к данным из различных служб, размещенных в разных местах, таких как Refinitiv Refinitiv Data Platform, Datastream Web Service, https://developers.refinitiv.com/en/api-catalog/refinitiv. -tick-history/refinitiv-tick-history-rth-rest-api и т. д. Однако этот пример реализации предназначен только для целей разработки и POC, а не для использования в производстве. Вы можете использовать сервер де-факто, такой как Nginx, для обратного прокси-сервера в вашей среде.
В то же время API Refinitiv Data Platform (RDP) предоставляют разработчикам различные данные и контент Refinitiv через простой в использовании веб-API. API-интерфейсы легко интегрируются в любое приложение и платформу, поддерживающую протокол HTTP и формат сообщений JSON.
Рекомендации
Для получения дополнительной информации, пожалуйста, ознакомьтесь со следующими ресурсами:
- Страница API Refinitiv Data Platform на веб-сайте Сообщество разработчиков Refinitiv.
- Страница Refinitiv Data Platform APIs Playground.
- API Refinitiv Data Platform: введение в API «запрос-ответ.
- API Refinitiv Data Platform: авторизация — все о токенах.
- Учебное пособие по RDP APis — Авторизация для браузерных приложений.
- Создание веб-приложения для отображения данных ESG с использованием Angular и RDP API — примеры API Refinitiv.
- Статья Ограничения и рекомендации для службы аутентификации RDP.
- Статья Как легко протестировать HTTP REST API с помощью Visual Studio Code — Thunder Client extensions.
- Статья Начало работы с Refinitiv Data Platform.
- Статья Как легко протестировать REST API Refinitiv Data Platform с помощью Visual Studio Code — клиентские расширения REST.
- Статья Использование RDP API для запроса данных ESG на Jupyter Notebook.
- Статья Используйте Fiddler для захвата RDP-взаимодействий.
По любым вопросам, связанным с API Refinitiv Data Platform, обращайтесь на Форум RDP API на Странице вопросов и ответов сообщества разработчиков.