Falcon Space. Создание сервиса API (входящие и исходящие запросы API)

Введение в API

В системе реализованы 2 механизм для работы API 

  • Универсальный механизм входящих запросов по API - позволяет извне запускать некоторые команды по HTTPS GET/POST и получать некий отклик в JSON/XML/Plain text формате.
  • Исходящие запросы к внешним API - система подготавливает запрос к внешней системе, отправляет его по HTTPS GET/POST и обрабатывает ответ. 

Подготовка исходящих запросов, обработка отклика от исходящих запросов, обработка входящих запросов - вся обработка происходит через хранимые процедуры. 

Управление API происходит на странице /asapi

Универсальный механизм входящих запросов по API

Как проходит основной процесс входящего запроса: 

  1. Обращение извне по HTTPS GET к методу auth для получения token доступа (система проверяет логин, пароль и выдает токен, который будет проверяться в дальнейших обращениях). 
  2. Отправка запроса action для выполнения некоего действия (Получить заказы, создать новый заказ). В рамках запроса происходит следующее:
    1. Проверяются права на выполнение операции
    2. Запускается хранимая процедура обработки действия, подготавливается ответ для вызывающей стороны в виде JSON, XML, Plain text.
    3. Выдается некий отклик на вызывающую сторону

Для API используются обычный HTTPS запросы с ответом в формате JSON. Основные методы

  • auth - создание сессии пользования API (параметры username, password)
  • action - выполнение некоего метода API (параметры могут быть любые)

Использование API

1. Вызываем по Get или Post метод авторизации /api/auth?username=&password={password}&output=json

  • Имя и пароль пользователя API задается в таблице as_api_users (это не логин/пароль обычного пользователя системы). 
  • output - необязательный параметр, задает формат вывода (json, xml,text).
Если данные корректные, то получим токен в отклике сервера. {"errorCode":0,"token":"7285440B-BD32-405F-813D-C26DFED23DF5","result":true,"msg":""}
Если есть ошибки, то result = false и errorCode содержит код ошибки. 

2. Вызываем метод API 

/api/action/getOrders?token=7285440B-BD32-405F-813D-C26DFED23DF5&catID=1

Передаем token, action (код метода) и произвольные параметры. 

Если все хорошо, то мы получаем result: true и в data содержатся выходные данные от результата выполнения метода. 
Коды ошибок и описания к ним: 

Код

Описание ошибки

1

100

Неверный токен

2

101

Истекло время сессии

3

102

Не найдена реализация метода АПИ (т.е. нет хранимой процедуры метода)

4

103

Выполнение метода завершилось с ошибкой

5

104

Имя/пароль неверные

Примечание: 
  1. в ExtendedDictionaryParameter @parameters используем Key, Value2, а не Key, Value!
  2. в @parameters также передается содержимое самого запроса Request.InputStream (в Key=InputStream)
  3. в @parameters также передается ключ remoteIP - IP вызывающий стороны (например, по нему можно проверить легитимность запроса к API)
  4. Если используете для отправки метод POST, то обязательно указывайте   'content-type': 'application/x-www-form-urlencoded'. Проверять подобные запросы можно через программу postman.

Создание нового метода API

API создается следующим образом: 

  1. Создается действие в таблице as_api_actions (на странице /asapi)
  • entityCode указывает код сущности, с которой мы работаем, например order
  • code - задает код действия. 

    2. Создается хранимая процедура api_{entityCode}_{code}, которая возвращает 2 select. 

CREATE procedure [dbo].[api_order_getOrders]
@parameters ExtendedDictionaryParameter READONLY, -- параметры которые переданы в метод
@username nvarchar(256) --пользователь API (это не логин пользователя в системе)
as
begin
	declare @catID int
	select @catID = cast(Value2 as int) from @parameters where [Key] = 'catID'

	/* select 1 - это информация об операции. В errorCode можно указать
          специфичные коды ошибок по операциям */
	select '' Msg, 1 Result, 0 errorCode

	/* select 2 - это данные, которые необходимо передать источнику запроса к API
        (в выходном JSON передаются в параметре data) */
	select * from ord_orders


        /* SELECT 3 Вызов внешних действий (напр Запрос API)*/

end

3.Вызываем метод как /api/action/actioncode1?token=token1&...{доп параметры}....

Вызов API без авторизации

В этом случае нет необходимости использовать токены.

  • У action укажите параметр withoutToken=true.
  • Вызывайте метод без токена: /api/action/getOrders?catID=1

Установка формата вывода для действия. 
Для этого укажите json,text или xml в параметре outputType для действия (as_api_actions). 

Cвойство идемпотентности для создаваемых методов API

Для включения идемпотентности необходимо в запросе к API передаваться определенный параметр или заголовок(напр X-Request-ID),
содержащий уникальный идентификатор: guid, комбинация из номера заказа, даты и суммы.
Каждый новый запрос, который необходимо обработать, должен включать новое значение X-Request-ID.
Таким образом можно избежать проблем с повторными запросами (когда операция дважды выполнится на сервере для 1 запроса).

Исходящие запросы к внешним API

Вы можете обратиться к внешним API через использование Внешних действий (код apirequest, использование описано в документации по Формам). 
Чтобы создать запрос, необходимо выполнить следующее:
  • создать запись о новом запросе (таблицы Исходящие запросы API на /asapi)
  • реализовать процедуру request(она выдает адрес и параметры для выполнения запроса)
    • На входе: @parameters ExtendedDictionaryParameter (коллекция входных параметров в Key nvarchar(32), Value2 nvarchar(max))  и @username (текущий пользователь)
    • Возвращает SELECT 1 (Msg, Result и URL, ContentType)
      • URL - адрес, который будет вызван по HTTPS
      • ContentType - можно задать для POST запросов свой ContentType (для формы).
        • По умолчанию он подставляется для форм multipart/form-data; boundary=------
        • и для json тела application/json
    • и SELECT 2 (параметры которые будут передаваться вовне - name, value, type). 
      • type - вариант form, header, json.
        • Если отправить надо post запрос, то параметры ставьте в form.
        • Если передан json (используется для POST) - то его содержимое будет телом всего запроса POST. Все остальные параметры в этом случае игнорируются.
        • Если нужны обычные get параметры - то передавайте их через URL
  • реализовать процедуру обработки ответа - response
    • На входе ответ от внешнего источника в виде строки @response, @parameters ExtendedDictionaryParameter (коллекция входных параметров в Key, Value2, которые приходили в Request процедуру)
    • Ответ
      • SELECT 1 Msg, Result и Response (может быть дополнительная обработка и выдача ответа вовне). 
      • SELECT 2 Вызов внешних действий (Внешние запросы API и т.д.)

Ответ при вызове API, например, из формы, передается в поле Response из SELECT 1. 

Туда можно передать полностью входную переменную @response без обработки, или результаты парсинга переменной @response в доступном для понимания виде.

Для тестирования API можно использовать метод /Api/Req/{code} - он вернет ответ в JSON формате. 
Пример хранимой процедуры request: 
CREATE PROCEDURE [dbo].[api_metrikaMonth_request]
	@parameters ExtendedDictionaryParameter READONLY,  -- входящие параметры для внутренней обработки (используйте Key, Value2)
	@username nvarchar(32)  -- текущий пользователь.
AS
BEGIN
	
    
declare @metrikaID nvarchar(256) 
	set @metrikaID = '53312170' -- Falcon

--set @metrikaID = '60713749' -- DEMO

declare @date1 nvarchar(256) = convert(nvarchar(10), dateadd(day, -30, getdate()), 120)  --2020-04-26
declare @date2 nvarchar(256) = convert(nvarchar(10), getdate(), 120)


declare @token nvarchar(256) = 'token...'
declare @url nvarchar(512) = 'https://api-metrika.yandex.net/stat/v1/data/bytime?'
    	+ 'id='+@metrikaID
    	+ '&preset=sources_summary'
        + '&group=day'
    	+ '&metrics=ym:s:users,ym:s:visits,ym:s:manPercentage,ym:s:womanPercentage' + 
        + '&date1=' + @date1   --2020-04-26
    	+ '&date2=' + @date2    -- 2020-04-26
    	-- SELECT 1  Msg, Result, Url (адрес, куда будет идти запрос)
	select '' Msg, 1 Result, @url Url 

	-- SELECT 2 PARAMETERS - параметры, которые будут передаваться во внешний источник
--	select 'Content-type' name, 'application/json' value, 'header' [type] -- form (в форме передается), header (в http headers), get запросы передавайте прямо в URL  
  --  union 
  --  select 'Accept' name, 'application/json' value, 'header' [type]
    --union
    select 'Authorization' name, 'OAuth '+ @token value, 'header' [type]
END
Пример response:
CREATE PROCEDURE [dbo].[api_metrikaMonth_response]
	@response nvarchar(max),
	@parameters ExtendedDictionaryParameter READONLY,  -- входящие параметры для внутренней обработки (используйте Key, Value2 - те же что и на request)
	
	@username nvarchar(32)
AS
BEGIN
	-- SELECT 1
	select '' Msg, 1 Result, @response Response

	-- SELECT 2 Внешние действия

END


Как отправить исходящий запрос POST с JSON телом?

Для этого указываем тип запроса POST и передаем в процедуре Request в SELECT 2 только 1 параметр с type=json в формате строки с JSON.


Примечание
Учитывайте длину кодов и ключей (не должны быть больше 32 символов).

Работа с JSON в SQL Server
https://docs.microsoft.com/ru-ru/sql/relational-databases/json/json-data-sql-server?view=sql-server-ver15
https://stackoverflow.com/questions/2867501/parse-json-in-tsql
https://habr.com/ru/post/343062/
https://habr.com/ru/post/317166/

Работа с XML в SQL Server 
https://www.sql.ru/forum/841296/razbor-xml-v-tablicu
https://stackoverflow.com/questions/15680259/parse-xml-in-sql-server/15681388
https://stackoverflow.com/questions/3989395/convert-xml-to-table-sql-server

Онлайн редакторы для XML и JSON

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

https://xmlgrid.net/ - просмотр XML

https://jsoneditoronline.org/ - редактор JSON

Платформа Falcon Space

Это снижение стоимости владения

за счет меньшего количества людей для поддержки

Это быстрое внесение изменений

по ходу эксплуатации программы

Это современный интерфейс

полная адаптация под мобильные устройства

Бесплатное обучение разработке на Falcon Space

Вы можете разрабатывать самостоятельно или сотрудничать с нами в плане веб-разработки на платформе Falcon Space.
Примечание