Создание расширенных соединителей данных (предварительная версия)

[Данная статья посвящена предварительному выпуску и может быть изменена.]

Если данные, которые вы хотите использовать с соединителем, структурированы в виде таблиц или списков, усовершенствованный протокол соединителя позволяет легко реализовать высокопроизводительный соединитель корпоративного уровня. Расширенные соединители служат мощным источником знаний для агентов и позволяют легко создавать canvas приложения в Power Apps и составлять логику с помощью Power Automate.

Это важно

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

Действия и улучшенные соединители

Соединители, созданные с помощью конечных точек OpenAPI (swagger), рассматриваются как действующие соединители. OpenAPI предоставляет стандартный формат для описания API HTTP любого размера. Он позволяет явно определять конечные точки (пути), поддерживаемые методы HTTP и схемы запросов и ответов. Каждая операция (сочетание пути и метода) представляет определенное вызываемое действие API, что делает его хорошо подходящим для API, которые соответствуют принципам RESTful.

Для структурированных источников данных подробный элемент управления OpenAPI становится обременительным, так как табличные источники данных обычно не определяются конечной точкой OpenAPI. Определение OpenAPI не привязано к метаданным, описывающим структурированные данные, поэтому он не адаптируется к изменениям, которые добавляют новые таблицы, столбцы или связи с источником данных. Соединитель, созданный с помощью статического определения OpenAPI, не может представлять эти изменения до повторного создания.

Для расширенных соединителей требуется конечная точка, которая содержит сведения, описывающие динамический набор таблиц, схем и возможностей. В этой статье описывается протокол, который можно реализовать для создания веб-API ASP.NET Core на основе протокола, аналогичного OData, а не OpenAPI. Этот протокол предназначен для табличных данных и использует возможности OData для управления фильтрацией, сортировкой, разбиением по страницам и связями, которые не предоставляют OpenAPI.

Замечание

Конечная точка, описанная в этой статье, имеет некоторые сходство с OData, но не реализует фактический протокол OData.

Структурированные данные

Что мы имеем в виду структурированными данными? Данные могут быть структурированы с помощью фактических таблиц баз данных, но они также могут использовать различные термины, такие как "сайт", а не "база данных" и "список", а не "таблица". Основная точка заключается в том, что данные структурированы в иерархию ресурсов следующим образом:

  • Набор данных предоставляет коллекцию таблиц
  • Таблица содержит строки и столбцы, содержащие данные
  • Элемент представляет строку таблицы

Соединители, использующие этот шаблон

Ниже приведены некоторые из расширенных соединителей, использующих этот шаблон:

DB2

Принцип работы

Расширенный протокол соединителя состоит из трех основных частей:

  • Конечные точки возможностей: описание наборов данных, таблиц и столбцов, к которые соединитель может получить доступ и что они могут сделать.
  • Транспилер: преобразует запросы стиля GET OData для получения данных для источника данных. Эти запросы используют такие параметры запросов OData, как $filter, $select, $orderbyи $sort$top
  • Реализация операции CUD. Описание выполнения операций создания, обновления и удаления ресурсов для источника данных

На высоком уровне необходимо реализовать следующий процесс:

  1. Создайте веб-API ASP.NET Core, который реализует расширенный протокол соединителя.
  2. Разверните проект веб-API ASP.NET Core в выбранной среде размещения.
  3. Создайте настраиваемый соединитель с помощью средства командной строки paconn.
  4. Настройте проверку подлинности.
  5. Поделитесь и протестируйте коннектор.

Замечание

Пример расширенного соединителя PowerFx — это решение Visual Studio, опубликованное на сайте GitHub. Вы можете клонировать репозиторий и использовать предоставленный проект ASP.NET Core Web API в качестве отправной точки для конечной точки.

Конечные точки возможностей

Расширенный протокол соединителя зависит от реализации пяти конечных точек, описывающих возможности службы. В следующей таблице перечислены эти конечные точки и содержатся ссылки на разделы этого документа, объясняющие их реализацию.

Маршрут Как
GET $metadata.json/datasets Возвращаемый список наборов данных
GET /datasets Возврат имен наборов данных
GET /datasets/{dataset}/tables Возвращать имена таблиц
GET $metadata.json/datasets/{dataset}/tables/{tableName} Возврат возможностей таблицы
GET /datasets/{dataset}/tables/{tableName}/items Получение значений столбцов таблицы

Интерфейс ITableProvider

ITableProviderFactory Следующие и ITableProvider интерфейсы предоставляют ожидаемые методы для реализации расширенных возможностей протокола соединителя. Добавьте следующий код в папку Services проекта веб-API ASP.NET Core.

// Helper to get a provider for a given auth token. 
public interface ITableProviderFactory
{
    ITableProvider Get(IReadOnlyDictionary<string, string> settings);
}

/// <summary>
/// Datasource Provider. Host implements this to provide the RecordTypes for a specific source.
/// </summary>
public interface ITableProvider
{
    // Return list of datasets (logical name, display name)
    public Task<DatasetResponse.Item[]> GetDatasetsAsync(
      CancellationToken cancellationToken = default
      );

    // Provider list of the tables.
    public Task<GetTablesResponse> GetTablesAsync(
      string dataset, 
      CancellationToken cancellationToken = default);

    public Task<RecordType> GetTableAsync(
      string dataset, 
      string tableName, 
      CancellationToken cancellationToken = default);

    public Task<TableValue> GetTableValueAsync(
      string dataset, 
      string tableName, 
      CancellationToken cancellationToken = default);
}

Реализуйте веб-API ASP.NET Core с разделением между интерфейсом (REST API) и серверной частью (поставщиком источников данных). Бэкэнд абстрагирован через ITableProvider интерфейс, который можно реализовать для подключения к любому табличному источнику данных.

Используемые классы

В создаваемом веб-приложении ASP.NET Core добавьте пакеты NuGet Microsoft.PowerFx.Connectors и Microsoft.PowerFx.Core , чтобы получить доступ к типам, используемым в ITableProvider, например RecordType и TableValue

Некоторые другие типы, которые вам нужны, в настоящее время не включены в пакеты NuGet PowerFx. Найдите их в примере Power Fx с расширенным соединителемпапке power-fx-enhanced-connector/CdpHelpers/Protocol, используя то же Microsoft.PowerFx.Connectors пространство имен. См. таблицу, описывающую эти типы.

Возвращаемый список наборов данных

Эта конечная точка в службе предоставляет легкий каталог в формате JSON всех контейнеров данных верхнего уровня — то, что в SQL можно представить как выполнение SELECT name FROM sys.databases. При выборе только имен и URL-адресов доступа каждого набора данных клиенты могут динамически обнаруживать, какие логические единицы (базы данных) служба предоставляет без жесткого написания каких-либо идентификаторов. Эта конструкция не только инициирует рабочие процессы UI или генерации кода, основанные на метаданных, позволяя пользователям выбирать набор данных и детализацию его таблиц или представлений, но также соблюдает правила доступа, возвращая только те наборы данных, которые разрешены для просмотра.

Реализуйте этот маршрут в контроллере, чтобы предоставить данные о доступных наборах данных:

GET $metadata.json/datasets

Замечание

Этот маршрут не включен в ITableProvider интерфейс.

Возвращает экземпляр DatasetMetadata , имеющий следующие свойства:

Имя Тип Description
DatasetFormat String Описывает формат строки набора данных. Например, для SQL это может быть "{server},{database}"
IsDoubleEncoding Boolean Указывает, закодирован ли бинарный блок метаданных дважды (например, полезные данные JSON, закодированные в формате JSON), для извлечения необработанных метаданных требуется два прохода декодирования.
Параметры IReadOnlyCollection<МетаданныеПараметр> См. MetadataParameter
Табличный МетаданныеTabular См. MetadataTabular

Замечание

В примере улучшенного соединителя Power FxCdpSampleWebApi/Controllers/CdpController.csDatasetMetadata переименовывается в DatasetMetadataResponse. Это имя будет согласовано с именами, используемыми в интерфейсе ITableProvider , если оно было включено.

Метаданные параметр

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

  • Пользовательские интерфейсы могут отображать четкие метки и подсказки для каждого параметра.
  • Обязательные поля применяются во время разработки, предотвращая ошибки среды выполнения.
  • Входные значения проверяются на объявленный тип (string, integer, boolean и т. д.).
  • Кодировка URL-адресов применяется правильно, поэтому специальные символы не прерывают запрос.

Задайте свойство DatasetMetadata.Parameters с экземпляром MetadataParameter , содержащим следующие свойства:

Имя Тип Description
Описание String Доступное для чтения объяснение того, что этот параметр представляет, и как он влияет на запрос набора данных. Например, это значение — имя сервера или имя базы данных в контексте SQL.
Имя String Имя параметра, которое клиенты должны включить в строку запроса или в тело запроса.
Required String Указывает, должен ли клиент предоставить этот параметр. Если значение равно true, пропуск параметра приводит к ошибке; если значение равно false, может применяться поведение по умолчанию или резервный вариант.
Тип String Тип данных значения параметра, например stringinteger, booleanкоторый сообщает клиентам, как проверить и преобразовать входные данные перед выдачой запроса.
UrlEncoding String Указывает, должно ли значение параметра быть закодировано один раз (single) или дважды (double).
XMsDynamicValues MetadataDynamicValues См. статью MetadataDynamicValues
XMsSummary String Краткая сводка, используемая в подсказках пользовательского интерфейса или документации, которая поможет пользователям понять назначение этого параметра на первый взгляд.

МетаданныеДинамическиеЗначения

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

  • Клиенты знают, к какой конечной точке или пути обращаться, чтобы получить текущий список значений.
  • Полезные данные ответа анализируются правильно, чтобы извлечь как базовые значения, так и их названия для отображения.
  • Входные данные параметров синхронизируются с доступными опциями вашей службы, что сокращает количество ошибок и улучшает пользовательский опыт.

При настройке коллекции DatasetMetadata.Parameters задайте свойству XMsDynamicValues экземпляр MetadataDynamicValues. Этот класс имеет следующие свойства строки:

Имя Description
Путь Относительный URL-адрес или путь OData, к которым клиенты обращаются для получения списка динамических значений (например: /datasets/{dataset name}/tables).
ValueCollection Имя свойства JSON в ответном сообщении, содержащем массив элементов (например, value или items).
ValuePath Путь JSON (относительно каждого элемента) для извлечения фактического значения параметра (например, id или name.value).
ValueTitle Путь JSON (относительно каждого элемента) для извлечения отображаемого текста для каждого параметра (например, displayName или title).

МетаданныеTabular

Эти метаданные сообщают клиентскому коду, как представить и получить доступ к табличным данным службы. Задав эти свойства, вы убедитесь, что пользовательские интерфейсы отображают терминологию и правильно создают URL-адреса для конкретной серверной части. Например, служба на основе SQL будет использовать Table/Tables, в то время как соединитель SharePoint будет использовать List/Lists; и правильные параметры кодирования URL-адресов гарантируют правильность построения путей ресурсов.

Задайте свойство DatasetMetadata.Tabular с экземпляром MetadataTabular, который содержит следующие строковые свойства:

Имя Description
DisplayName Отображаемое имя набора данных. Например, Database/WebSite.
Источник Это может быть mru или singleton. Если служба имеет только один логический контейнер данных, то /datasets фактически становится одноэлементной конечной точкой. В сценарии с несколькими наборами данных все равно не требуется перегружать клиенты с каждым возможным набором данных одновременно. Вместо этого вы отслеживаете журнал использования и /datasets возвращаете только первые N наборы данных, упорядоченные по времени последнего доступа (или последней модификации). Таким образом, пользователи видят последние использованные (mru) на первом месте, а затем могут перейти к полному списку или включить постраничную разбивку, если им нужно больше.
TableDisplayName Отображаемое имя таблицы, например источника данных, например Table или List.
TablePluralName Имя множественного числа таблицы, например источника данных, например "Таблицы" или "Списки".
UrlEncoding Может иметь значение single или double.

Возвратите имена наборов данных

Реализуйте этот маршрут в контроллере, чтобы предоставить коллекцию имен для каждого набора данных:

GET /datasets

Реализуйте метод ITableProvider.GetDatasetsAsync для возврата экземпляра DatasetResponse, который имеет свойство value с массивом экземпляров Item.

У каждого Item есть свойства строки Name и DisplayName.

Замечание

Соединители не требуются для предоставления нескольких наборов данных. Если существует только один набор данных, то по соглашению следует установить как свойства Name, так и свойства DisplayName одного элемента в default.

Возвращать имена таблиц

Реализуйте этот маршрут в контроллере, чтобы предоставить коллекцию имен для таблиц в наборе данных:

GET /datasets/{dataset}/tables

Реализовать метод ITableProvider.GetTablesAsync для возврата экземпляра GetTablesResponse. Этот класс имеет Value свойство, возвращающее значение List<RawTablePoco>.

RawTablePoco имеет два строковых свойства: Name и DisplayName.

Замечание

PoCO означает "Обычные старые объекты CLR" и используется в качестве способа форматирования данных ответа в ASP.NET Core Web API.

Возврат возможностей таблицы

Реализуйте этот маршрут в контроллере для возврата данных о возможностях таблиц в наборе данных:

GET $metadata.json/datasets/{dataset}/tables/{tableName}

Реализуйте метод, возвращающий RecordType, затем преобразуйте это значение в GetTableResponse. Метод RecordType.ToTableResponse содержит пример, показывающий, как. Чтобы использовать его, необходимо добавить файл CdpHelpers/RecordTypeExtensions.cs в проект.

GetTableResponse имеет следующие свойства:

Имя Тип Description
capabilities CapabilitiesPoco Возвращает или задает возможности таблицы, такие как фильтрация и поддержка сортировки. См . статью "Описание возможностей таблицы"
name String Возвращает или задает имя таблицы.
permissions String Возвращает или задает разрешения для таблицы (например, "чтение и запись").
schema TableSchemaPoco Возвращает или задает схему таблицы. См . статью "Описание возможностей столбцов таблицы"

Описание возможностей таблицы

Свойство GetTableResponse.capabilities описывает возможности таблицы с помощью класса CapabilitiesPoco .

Класс CapabilitiesPoco имеет следующие свойства для описания возможностей таблицы.

Имя Тип Description
filterFunctionSupport string[] Возвращает или задает поддерживаемые функции фильтра (например, eq, and). or
filterRestrictions Filter Класс Filter имеет логическое filterable свойство, описывающее, поддерживает ли таблица фильтрацию вообще. Если filterable задано значение true, nonFilterableProperties свойство содержит массив имен столбцов таблицы, которые не могут быть фильтруемыми.
isOnlyServerPagable bool Возвращает или задает значение, указывающее, доступна ли таблица только для страниц сервера.
odataVersion int Возвращает или задает версию OData (например, 3).
serverPagingOptions string[] Возвращает или задает параметры разбиения серверов (например, top, skiptoken).
sortRestrictions Sort Класс Sort имеет логическое sortable свойство, описывающее, поддерживает ли таблица любую сортировку. Если sortable задано значение true, unsortableProperties свойство содержит массив имен столбцов таблиц, которые не сортируются.

Описание возможностей столбцов таблицы

Свойство GetTableResponse.schema описывает возможности столбцов таблиц с помощью класса TableSchemaPoco .

Замечание

В этом разделе описывается набор классов с простыми и сложными свойствами. Свойства с сложным типом создают иерархию, описывающую возможности столбцов для таблицы.

TableSchemaPoco.items
 Items.properties
  ColumnInfo.capabilities
   ColumnCapabilitiesPoco

Класс TableSchemaPoco имеет следующие свойства для описания возможностей таблицы.

Имя Тип Description
type струна Возвращает или задает тип схемы (по умолчанию — массив).
items элементы Возвращает или задает определение элементов, описывающее столбцы таблицы.

Класс Items имеет следующие свойства:

Имя Тип Description
type струна Возвращает или задает тип элементов (по умолчанию — "объект").
properties Словарьстрок,ColumnInfo Возвращает или задает словарь свойств столбцов, с именем столбца в качестве ключа.

Класс ColumnInfo имеет следующие свойства:

Имя Тип Description
title струна Возвращает или задает заголовок столбца.
description струна Возвращает или задает описание столбца.
type струна Возвращает или задает тип столбца (например, integer, string).
sort струна Возвращает или задает возможности сортировки для столбца (например, asc, desc).
capabilities ColumnCapabilitiesPoco Возвращает или задает возможности фильтра для столбца.

Класс ColumnCapabilitiesPoco имеет следующие свойства:

Имя Тип Description
filterFunctions строка[] Возвращает или задает поддерживаемые функции фильтра для столбца (например, eq, and). or

Получение значений столбцов таблицы

Реализуйте этот маршрут в контроллере для возврата значений столбцов таблицы:

GET /datasets/{dataset}/tables/{tableName}/items

ITableProvider.GetTableValueAsync Реализуйте метод для возврата TableValue, а затем преобразуйте это значение в GetItemsResponse

GetItemsResponse имеет только одно свойство value, которое является List<Dictionary<string, object>>, содержащим ключи и значения для соответствующих свойств таблицы.

Транспилер

Создаваемый веб-API ASP.NET Core должен позволить пользователям указывать необязательные параметры строки запроса OData при использовании этого маршрута:

GET /datasets/{dataset}/tables/{tableName}/items

Служба должна поддерживать функции, заявленные для таблицы и столбцов.

CdpSampleWebApi/Services/ODataQueryModel.cs — это упрощенный контейнер привязки модели для подмножества параметров системного запроса OData. Его назначение:

  • Привязка модели: ASP.NET автоматически заполняет его свойства из параметров строки запроса с именем $select, $filter$topи $orderby благодаря атрибутам[FromQuery(Name="...")]. Например: /entities?$select=id,name&$top=10.

  • Только необработанный захват: он не анализирует и не проверяет выражения OData; он сохраняет предоставленный клиентом текст, поэтому последующий код (например, слой данных или передатчик к другому API) может решить, как интерпретировать, проверять или пересылать их.

  • Условная упаковка: ToStrDict() преобразует только указанные значения (и $top только если > 0) в словарь, полезно для:

    • Восстановление или переадресация одинаковых параметров запроса OData в другую службу.
    • Ведение журнала и аудит.
    • Создание строки запроса программным способом.
  • Выбор именования/регистра: top и orderby прописаны строчными буквами, чтобы точно отображать ключевые слова OData (предупреждения стиля/анализатора подавлены в начале файла). Выбор и фильтрация используют PascalCase (смешанный стиль), но привязка по-прежнему работает из-за явного переопределения имени.

  • Область: она намеренно пропускает другие параметры OData ($skip, , $expand,$count$searchи другие), сохраняя минимальное количество поверхностей. Возможные улучшения (при необходимости):

    • Сделайте верхний nullable (int?), чтобы различать "отсутствующий" и "явный 0".
    • Добавьте $skip, $expandили другие параметры запроса по мере увеличения требований.
    • Добавление проверки или синтаксического анализа (например, утверждение полей в $select, анализ выражений для $filter).
    • Нормализация именования свойств для согласованности.

Короче говоря, ODataQueryModel класс представляет собой простой посредник для передачи выбранных параметров запроса OData, обеспечивая безопасный, четкий и тестируемый доступ к ним внутри действий контроллера или служб.

Реализация операций создания, обновления и удаления

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

Создание строк

Служба должна использовать POST метод HTTP с тем же путем ресурса, который используется для получения записей. Полезные данные отправляются с телом запроса.

POST /datasets/{dataset}/tables/{tableName}/items

Обновление и удаление строк

Для обновления или удаления строк требуется какой-либо способ определить запись, которую требуется изменить или удалить. Это зависит от характера источника данных, но следует использовать те же пути к ресурсам. Чтобы изменить запись, используйте PATCH.

PATCH /datasets/{dataset}/tables/{tableName}/items/{primary key}

Чтобы удалить запись, используйте DELETE.

DELETE /datasets/{dataset}/tables/{tableName}/items/{primary key}

Ограничения

Ниже приведены области, в которых общие возможности табличных данных не включены с помощью протокола подключения к табличным данным.

Отношения

В настоящее время невозможно моделировать связи между таблицами.

Типы данных ограничены

Будут работать только типы, поддерживаемые Swagger 2.0.

Дальнейшие шаги

Узнайте о примере использования расширенного соединителя.