Creatio development guide

DataService. Чтение записи. Пример

Glossary Item Box

Общие положения

Веб-служба DataService приложения bpm'online является RESTful-сервисом, т.е. поддерживает передачу состояния представления (Representational State Transfer, REST). В общем случае REST является очень простым интерфейсом управления информацией без использования каких-то дополнительных внутренних прослоек, т.е. данные не нужно преобразовывать в какой-либо сторонний формат, например, XML. В простом RESTful-сервисе каждая единица информации однозначно определяется глобальным идентификатором, таким как URL. Каждый URL, в свою очередь, имеет строго заданный формат. Однако это не всегда удобно для передачи больших массивов данных.

В DataService данные автоматичеcки могут быть сконфигурированы в различные форматы данных, такие как XML, JSON, HTML, CSV и JSV. Структура данных определяется так называемыми контрактами данных. Полный перечень контрактов данных, используемых службой DataService, изложен в статье "Веб-служба DataService".

Контракт данных SelectQuery

Для чтения записей раздела используется контракт данных SelectQuery. Передача данных запроса в службу DataService осуществляется по HTTP протоколу при помощи POST запроса по следующему URL:

// Формат URL для POST-запроса на чтение данных из DataService.
http(s)://[Адрес приложения bpm'online]/[Номер конфигурации]/dataservice/[Формат данных]/reply/SelectQuery
// Пример URL для POST-запроса на чтение данных к DataService.
http(s)://example.bpmonline.com/0/dataservice/json/reply/SelectQuery

Контракт данных SelectQuery имеет сложную иерархическую структуру с несколькими уровнями вложенности. В серверной части ядра приложения bpm'online он представлен классом SelectQuery пространства имен Terrasoft.Nui.ServiceModel.DataContract библиотеки классов Terrasoft.Nui.ServiceModel.dll. Для простоты восприятия иерархическую структуру контракта данных SelectQuery удобно представить в формате объекта JSON:

{
    "RootSchemaName":"[Имя корневой схемы объекта]",
    "OperationType":[Тип операции с записью],
    "Columns":{
        "Items":{
            "Name":{
                "OrderDirection":[Порядок сортировки],
                "OrderPosition":[Позиция колонки],
                "Caption":"[Заголовок]",
                "Expression":{
                    "ExpressionType":[Тип выражения],
                    "ColumnPath":"[Путь к колонке]",
                    "Parameter":[Параметр],
                    "FunctionType":[Тип функции],
                    "MacrosType":[Тип макроса],
                    "FunctionArgument":[Аргумент функции],
                    "DatePartType":[Тип части даты],
                    "AggregationType":[Тип агрегации],
                    "AggregationEvalType":[Область применения агрегации],
                    "SubFilters":[Вложенные фильтры]
                }
            }
        }
    },
    "AllColumns":[Признак выбора всех колонок],
    "ServerESQCacheParameters":{
        "CacheLevel":[Уровень кеширования],
        "CacheGroup":[Группа кеширования],
        "CacheItemName":[Ключ записи в хранилище]
    },
    "IsPageable":[Признак разбиения на страницы],
    "IsDistinct":[Признак уникальности],
    "RowCount":[Количество выбираемых записей],
    "ConditionalValues":[Условия для построения постраничного запроса],
    "IsHierarchical":[Признак иерархической выборки данных],
    "HierarchicalMaxDepth":[Максимальный уровень вложенности иерархического запроса],
    "HierarchicalColumnName":[Имя колонки, использующейся для построения иерархического запроса],
    "HierarchicalColumnValue":[Начальное значение иерархической колонки],
    "Filters":[Фильтры]
    }
}

Основные свойства класса SelectQuery и их возможные значения представлены в таблице 1.

Табл. 1. — Свойства класса SelectQuery

Свойство Тип Описание
RootSchemaName string Строка, содержащая название корневой схемы объекта добавляемой записи.
OperationType QueryOperationType

Тип операции с записью. Задается значением перечисления QueryOperationType пространства имен Terrasoft.Nui.ServiceModel.DataContract. Для SelectQuery устанавливается значение QueryOperationType.Select.

Значения перечисления QueryOperationType:

Select 0
Insert 1
Update 2
Delete 3
Batch 4
Columns SelectQueryColumns Содержит коллекцию колонок для считываемых записей. Имеет тип SelectQueryColumns, определенный в пространстве имен Terrasoft.Nui.ServiceModel.DataContract. Следует конфигурировать, если значение признака AllColumns установлено как false и нужен определенный набор колонок корневой схемы, не включающий колонку [Id].
AllColumns bool Признак выбора всех колонок. Если значение установлено как true, в результате выполнения запроса будут выбраны все колонки корневой схемы.
ServerESQCacheParameters ServerESQCacheParameters Параметры кэширования EntitySchemaQuery на сервере. Тип ServerESQCacheParameters определен в пространстве имен Terrasoft.Nui.ServiceModel.DataContract.
IsPageable bool Признак постраничной выборки данных.
IsDistinct bool Признак, указывающий, убирать или нет дубли в результирующем наборе данных.
RowCount int Количество выбираемых строк. По умолчанию содержит значение -1, т.е. выбираются все строки .
ConditionalValues ColumnValues Условия для построения постраничного запроса. Тип ColumnValues определен в пространстве имен Terrasoft.Nui.ServiceModel.DataContract.
IsHierarchical bool Признак иерархической выборки данных.
HierarchicalMaxDepth int Максимальный уровень вложенности иерархического запроса.
hierarchicalColumnName string Имя колонки, использующейся для построения иерархического запроса.
hierarchicalColumnValue string Начальное значение иерархической колонки, от которого будет строиться иерархия.
Filters Filters Коллекция фильтров запросов. Имеет тип Filters, определенный в пространстве имен Terrasoft.Nui.ServiceModel.DataContract.
ColumnValues ColumnValues Содержит коллекцию значений колонок добавляемой записи. Имеет тип ColumnValues, определенный в пространстве имен Terrasoft.Nui.ServiceModel.DataContract.

Класс SelectQueryColumns имеет единственное свойство Items, которое определено как коллекция ключей и значений Dictionary<string, SelectQueryColumn>. Ключом является строка с названием добавляемой колонки, а значением — экземпляр класса SelectQueryColumn, который определен в пространстве имен Terrasoft.Nui.ServiceModel.DataContract. Свойства класса SelectQueryColumn приведены в табл. 2.

Табл. 2. — Свойства класса SelectQueryColumn

Свойство Тип Описание
OrderDirection OrderDirection Направление сортировки. Задается значением перечисления OrderDirection пространства имен Terrasoft.Common, определенного в библиотеке классов Terrasoft.Common.
OrderPosition int Задает номер позиции в коллекции колонок запроса, по которой производится сортировка.
Caption string Заголовок колонки.
Expression ColumnExpression Свойство, определяющее выражение типа выбираемой колонки.

Класс ColumnExpression определяет выражение, задающее тип колонки схемы. Он определен в пространстве имен Terrasoft.Nui.ServiceModel.DataContract библиотеки Terrasoft.Nui.ServiceModel. Свойства экземпляра этого класса заполняются в зависимости от свойства ExpressionType, которое и задает тип выражения. Полный перечень свойств класса ColumnExpression приведен в табл. 3.

Табл. 3. — Основные свойства класса ColumnExpression

Свойство Тип Описание
ExpressionType EntitySchemaQueryExpressionType

Тип выражения, определяющий значение, которое будет содержаться в добавляемой колонке. Задается значением перечисления EntitySchemaQueryExpressionType пространства имен Terrasoft.Core.Entities, определенного в библиотеке классов Terrasoft.Core. Для InsertQuery устанавливается значение EntitySchemaQueryExpressionType.Parameter.

Значения перечисления EntitySchemaQueryExpressionType:

SchemaColumn 0 Колонка схемы
Function 1 Функция
Parameter 2 Параметр
SubQuery 3 Вложенный запрос
ArithmeticOperation 4 Арифметическая операция
ColumnPath string Путь к колонке относительно корневой схемы. Правила построения путей см. в статье "Использование EntitySchemaQuery для построения запросов к базе данных".
Parameter Parameter

Определяет значение, которое будет содержаться в добавляемой колонке. Имеет тип Parameter, определенный в пространстве имен Terrasoft.Nui.ServiceModel.DataContract.

FunctionType FunctionType

Тип функции. Задается значением из перечисления FunctionType, определенного в пространстве имен Terrasoft.Nui.ServiceModel.DataContract.

Значения перечисления FunctionType:

None 0 Не определен
Macros 1 Макрос
Aggregation 2 Агрегирующая функция
DatePart 3 Часть даты
Length 4 Длина
MacrosType EntitySchemaQueryMacrosType

Тип макроса. Задается значением перечисления EntitySchemaQueryMacrosType, определенного в пространстве имен Terrasoft.Core.Entities.

FunctionArgument BaseExpression Аргумент функции. Принимает значение, если функция определена с параметром. Класс BaseExpression определен в пространстве имен Terrasoft.Nui.ServiceModel.DataContract, является предком для класса ColumnExpresion и имеет такой же набор свойств.
DatePartType DatePart

Часть даты. Задается значением из перечисления DatePart, определенного в пространстве имен Terrasoft.Nui.ServiceModel.DataContract.

Значения перечисления DatePart:

None 0 Не определен
Day 1 День
Week 2 Неделя
Month 3 Месяц
Year 4 Год
Weekday 5 День недели
Hour 6 Час
HourMinute 7 Минута

AggregationType

AggregationType Тип агрегирующей функции. Задается значением из перечисления AggregationType, определенного в пространстве имен Terrasoft.Common, определенного в библиотеке классов Terrasoft.Common.
AggregationEvalType AggregationEvalType Область применения агрегирующей функции. Задается значением из перечисления AggregationEvalType, определенного в пространстве имен Terrasoft.Core.DB, определенного в библиотеке классов Terrasoft.Core.
SubFilters Filters Коллекция фильтров вложенных запросов. Имеет тип Filters, определенный в пространстве имен Terrasoft.Nui.ServiceModel.DataContract.

Класс Parameter определен в пространстве имен Terrasoft.Nui.ServiceModel.DataContract. Его свойства приведены в табл. 4.

Табл. 4. — Свойства класса Parameter

Свойство Тип Описание
DataValueType DataValueType

Тип данных значения, которое будет содержаться в добавляемой колонке. Задается значением перечисления DataValueType пространства имен Terrasoft.Nui.ServiceModel.DataContract

Значения перечисления DataValueType:

Guid 0
Text 1
Integer 4
Float 5
Money 6
DateTime 7
Date 8
Time 9
Lookup 10
Enum 11
Boolean 12
Blob 13
Image 14
ImageLookup 16
Color 18
Mapping 26
Value object

Объект, содержащий значение добавляемой колонки.

ArrayValue string[]

Массив значений добавляемой колонки. Используется при сериализации массивов и BLOB данных.

ShouldSkipConvertion

bool

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

Класс ServerESQCacheParameters определен в пространстве имен Terrasoft.Nui.ServiceModel.DataContract. Его свойства приведены в табл. 5.

Табл. 5. — Свойства класса ServerESQCacheParameters

Свойство Тип Описание
CacheLevel int

Уровень размещения данных в кэше EntitySchemaQuery.

CacheGroup string

Группа кэширования.

CacheItemName string

Ключ записи в хранилище.

Класс Filters определен в пространстве имен Terrasoft.Nui.ServiceModel.DataContract. Подробности о свойствах этого класса и пример его использования изложены в статье "DataService. Фильтрация данных".

Пример чтения записей в стороннем приложении

Описание кейса

Необходимо создать консольное приложение, которое, используя службу DataService, прочитает записи раздела [Контакт] со следующими колонками:

  • Id;
  • ФИО;
  • Количество активностей — агрегирующая колонка, отображающая количество активностей данного контакта.

Алгоритм реализации кейса

1. Создать и настроить проект консольного приложения C#

Используя среду разработки Microsoft Visual Studio (версии не ниже 2012 Update 4), необходимо создать проект консольного приложения Visual C#, указав в качестве названия проекта, например, DataServiceSelectExample. Свойству проекта [Target framework] необходимо установить значение .NET Framework 4.5.

В секцию References проекта нужно добавить зависимости от следующих библиотек:

  • System.Web.Extensions.dll — библиотека классов, входящая в .NET Farmework;
  • Terrasoft.Core.dll — библиотека основных классов серверного ядра приложения. Можно найти по следующему пути: [Каталог с установленным приложением]\Terrasoft.WebApp\bin\Terrasoft.Core.dll;
  • Terrasoft.Nui.ServiceModel.dll — библиотека классов служб приложения. Можно найти по следующему пути: [Каталог с установленным приложением]\Terrasoft.WebApp\bin\Terrasoft.Nui.ServiceModel.dll;
  • Terrasoft.Common.dll — библиотека основных классов серверного ядра приложения. Можно найти по следующему пути: [Каталог с установленным приложением]\Terrasoft.WebApp\bin\Terrasoft.Common.dll.

В файл исходного кода приложения необходимо добавить директивы using:

using System;
using System.Text;
using System.IO;
using System.Net;
using System.Collections.Generic;
using Terrasoft.Nui.ServiceModel.DataContract;
using Terrasoft.Core.Entities;
using System.Web.Script.Serialization;
using Terrasoft.Common;

2. В исходный код приложения добавить объявления полей и констант

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

// Основной URL приложения bpm'online. Необходимо заменить на пользовательский.
private const string baseUri = @"http://example.bpmonline.com";
// Строка запроса к методу Login сервиса AuthService.svc.
private const string authServiceUri = baseUri + @"/ServiceModel/AuthService.svc/Login";
// Строка пути запроса SelectQuery.
private const string selectQueryUri = baseUri + @"/0/DataService/json/SyncReply/SelectQuery";
// Cookie аутентификации bpm'online.
private static CookieContainer AuthCookie = new CookieContainer();

Здесь объявлены три строковых константных поля, с помощью которых формируются пути выполнения запросов на аутентификацию и запросов на чтение данных. Данные об аутентификации будут сохранены в поле AuthCookie.

3. Добавить метод, выполняющий аутентификацию в приложении bpm'online

Для доступа создаваемого приложения к веб-службе DataService необходимо выполнить аутентификацию.

Алгоритм действия и пример реализации метода, который выполняет запрос к службе AuthService.svc для аутентификации пользователя, подробно изложены в статье Аутентификация внешних запросов к веб-сервисам bpm'online.

4. Добавить непосредственную реализацию запроса на добавление записи

Поскольку объявленная ранее константа selectQueryUri содержит путь для отправки данных в формате JSON, то отправляемые данные нужно предварительно сконфигурировать в виде строки, содержащей описание JSON-объекта, соответствующего контракту данных SelectQuery. Это можно сделать непосредственно в некоторой строчной переменной, однако намного удобнее и безопаснее с точки зрения возможности возникновения ошибок — создать экземпляр класса SelectQuery, заполнить его свойства, а затем сериализовать его в строку. Сделать это можно, добавив следующий исходный код:

// Экземпляр класса запроса.
var selectQuery = new SelectQuery()
{
    // Название корневой схемы.
    RootSchemaName = "Contact",
    // Коллекция колонок запроса.
    Columns = new SelectQueryColumns()
};
// Выражение, задающее тип колонки [[ФИО].
var columnExpressionName = new ColumnExpression()
{
    // Тип выражения — колонка схемы.
    ExpressionType = EntitySchemaQueryExpressionType.SchemaColumn,
    // Путь к колонке.
    ColumnPath = "Name"
};
// Конфигурирование колонки [Name]. 
var selectQueryColumnName = new SelectQueryColumn()
{
    //Заголовок.
    Caption = "ФИО",
    // Направление сортировки — по возрастанию.
    OrderDirection = OrderDirection.Ascending,
    // Позиция порядка сортировки.
    OrderPosition = 0,
    // Выражение, задающее тип колонки.
    Expression = columnExpressionName
};
// Выражение, задающее тип колонки [Количество активностей].
var columnExpressionActivitiesCount = new ColumnExpression()
{
    // Тип выражения — вложенный запрос.
    ExpressionType = EntitySchemaQueryExpressionType.SubQuery,
    // Путь к колонке относительно корневой схемы.
    ColumnPath = "[Activity:Contact].Id",
    // Тип функции — агрегирующая.
    FunctionType = FunctionType.Aggregation,
    // Тип агрегации — количество.
    AggregationType = AggregationType.Count
};
// Конфигурирование колонки [Количество активностей].
var selectQueryColumnActivitiesCount = new SelectQueryColumn()
{
    //Заголовок.
    Caption = "Количество активностей",
    // Направление сортировки — по возрастанию.
    OrderDirection = OrderDirection.Ascending,
    // Позиция порядка сортировки.
    OrderPosition = 1,
    // Выражение, задающее тип колонки.
    Expression = columnExpressionActivitiesCount
};

// Добавление колонок в запрос.
selectQuery.Columns.Items = new Dictionary<string, SelectQueryColumn>()
{
    {
        "Name",
        selectQueryColumnName
    },
    {
        "ActivitiesCount",
        selectQueryColumnActivitiesCount
    }
};
// Сериализация экземпляра класса запроса на добавление в JSON-строку.
var json = new JavaScriptSerializer().Serialize(selectQuery);

На завершающем шаге необходимо выполнить POST-запрос к службе DataService. Для этого необходимо создать экземпляр класса HttpWebRequest, заполнить его свойства, присоединить к запросу созданную ранее строку с JSON-объектом, а затем выполнить и обработать результат запроса к службе DataService. Для этого нужно добавить следующий исходный код:

// Преобразование строки JSON-объекта в массив байтов.
byte[] jsonArray = Encoding.UTF8.GetBytes(json);
// Создание экземпляра HTTP-запроса.
var selectRequest = HttpWebRequest.Create(selectQueryUri) as HttpWebRequest;
// Определение метода запроса.
selectRequest.Method = "POST";
// Определение типа содержимого запроса.
selectRequest.ContentType = "application/json";
// Добавление полученных ранее аутентификационных cookie в запрос на получение данных.
selectRequest.CookieContainer = AuthCookie;
// Установить длину содержимого запроса.
selectRequest.ContentLength = jsonArray.Length;
// Помещение JSON-объекта в содержимое запроса .
using (var requestStream = selectRequest.GetRequestStream())
{
    requestStream.Write(jsonArray, 0, jsonArray.Length);
}
// Выполнение HTTP-запроса и получение ответа от сервера.
using (var response = (HttpWebResponse)selectRequest.GetResponse())
{
    // Вывод ответа в консоль.
    using (StreamReader reader = new StreamReader(response.GetResponseStream()))
    {
        Console.WriteLine(reader.ReadToEnd());
    }
}

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

Пример чтения записей в приложении bpm'online

Описание кейса

Добавить в раздел [Контакты] кнопку при нажатии на которую вызывается метод, который, используя службу DataService, прочитает записи раздела [Контакты] со следующими колонками:

  • Id;
  • ФИО;
  • Количество активностей — агрегирующая колонка, отображающая количество активностей данного контакта.

Алгоритм реализации кейса

1. Добавить в раздел [Контакты] кнопку

Процесс добавления кнопки в раздел подробно описан в статье "Добавление кнопки в раздел".

Для рассматриваемого кейса необходимо создать замещающий клиентский модуль раздела [Контакты] (рис. 1).

Рис. 1. — Свойства замещающего клиентского модуля

В созданной клиентской схеме добавить локализуемую строку SelectQueryContactButtonCaption, для которой установить значение "Выбор контактов" (рис. 2).

Рис. 2. — Свойства локализуемой строки

В массив diff добавить конфигурационный объект с настройками расположения кнопки на странице.

//Настройка визуализации кнопки в разделе.
diff: /**SCHEMA_DIFF*/[
    // Метаданные для добавления в раздел пользовательской кнопки.
    {
        // Указывает на то, что выполняется операция добавления элемента на страницу.
        "operation": "insert",
        // Мета-имя родительского элемента управления, в который добавляется кнопка.
        "parentName": "ActionButtonsContainer",
        // Указывает на то, что кнопка добавляется в коллекцию элементов управления
        // родительского элемента (мета-имя которого указано в parentName).
        "propertyName": "items",
        // Мета-имя добавляемой кнопки.
        "name": "SelectQueryContactButton",
        // Дополнительные свойства элемента.
        "values": {
            // Тип добавляемого элемента — кнопка.
            itemType: Terrasoft.ViewItemType.BUTTON,
            // Привязка заголовка кнопки к локализуемой строке схемы.
            caption: { bindTo: "Resources.Strings.SelectQueryContactButtonCaption" },
            // Привязка метода-обработчика нажатия кнопки.
            click: { bindTo: "onSelectQueryContactClick" },
            "layout": {
                "column": 1,
                "row": 6,
                "colSpan": 1
            }
        }
    }

]/**SCHEMA_DIFF*/

2. Добавить метод-обработчик события нажатия кнопки

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

methods: {
    // Метод-обработчик нажатия кнопки.
    onSelectQueryContactClick: function() {
        // Создание экземпляра класса Terrasoft.InsertQuery.
        var select = Ext.create("Terrasoft.EntitySchemaQuery", {
            // Название корневой схемы.
            rootSchemaName: "Contact"
        });
        // Добавление в запрос колонки [ФИО].
        select.addColumn("Name");
        // Добавление в запрос агрегирующей колонки [Количество активностей].
        select.addAggregationSchemaColumn(
            // Путь к колонке относительно корневой схемы.
            "[Activity:Contact].Id",
            // Тип агрегации — количество.
            Terrasoft.AggregationType.COUNT,
            // Заголовок колонки.
            "ActivitiesCount",
            // Область применения агрегирующей функции — для всех элементов.
            Terrasoft.AggregationEvalType.ALL);
        // Запрос к серверу на обновление данных
        // Получение всей коллекции записей и ее отображение в консоли браузера.
        select.getEntityCollection(function(result) {
            if (!result.success) {
                // Обработка/логирование ошибки.
                this.showInformationDialog("Ошибка запроса данных");
                return;
            }
            // Выводимое сообщение.
            var message = "";
            // Перебор результирующей коллекции и построение выводимого сообщения.
            result.collection.each(function(item) {
                message += "ФИО: " + item.get("Name") +
                ". Количество активностей: " + item.get("ActivitiesCount") + "\n";
            });
            // Вывод сообщения в консоль.
            window.console.log(message);
        }, this);
    }
}

К СВЕДЕНИЮ

В отличие от предыдущего примера, авторизация не требуеся, поскольку программный код выполняется непосредственно в приложении bpm'online.

В клиентской части ядра приложения отсутствует класс, аналогичный классу SelectQuery в серверной части ядра. Для выбора данных некоторого раздела необходимо использовать класс Terrasoft.EntitySchemaQuery. Подробнее о свойствах и методах этого класса можно узнасть из статьи "Использование EntitySchemaQuery для чтения данных из БД" или в документации по API здесь.

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

Смотрите также

© Terrasoft 2002-2016.

Был ли данный материал полезен?

Как можно улучшить эту статью?