StoryCLM .NET SDK позволяет легко интегрировать систему StoryCLM c Вашим приложением на .NET. Данная библиотека сделана на базе REST API сервиса StoryCLM и максимально упращает работу с API.
Ниже будет рассказано как устаносить библиотеку, настроить проект для работы с ней и показана работа SDK на конкретных примерах.
- .NET Standard 1.1
Установить SDK можно двумя способами:
- NuGet Package Manager.
- Загрузить SDK непосредственно из этого репозитория.
NuGet Package Manager должен быть предварительно установлен и настроен в Visual Studio 2015 или более поздей версии.
Установка через NuGet Package Manager с использованием консоли
Выполните следующую команду в консоли NuGet Package Manager для установки SDK и всех его зависимостей:
PM> Install-Package StoryCLM
Установка через NuGet Package Manager с использованием расширения Visual Studio
Чтобы установить SDK с помощью расширения Visual Studio NuGet, выполните следующие действия:
- В обозревателе решений щелкните правой кнопкой мыши на проект и выберите "Управление NuGet пакетами".
- В поиске введите "StoryCLM" и нажмите Enter.
- После завершения поиска, выберете из списка StoryCLM .NET SDK и нажмите кнопку "Установить".
Перейдите в корневой каталог репозитория и нажмите на кнопку "Clone or вownload".
Подключение пространств имен
В файл, в котором Вы хотите использовать SDK, необходимо добавить следующий код:
using StoryCLM.SDK;
using StoryCLM.SDK.Models;
Получени учетных данных
Для того что бы получить доступ к API своего клиента нужно на панели администрирования создать и настроить приложение.
Более подробную информацию о учетных данных, типах клиента, о аутентификации и авторизации в системе нужно ознакомиться с документацией по REST API.
Использование класса SCLM
SCLM - это класс-контекст, который содержит методы для работы с API StoryCLM. Для работы нужно создать экземпляр класса SCLM и пройти аутентификацию.
SCLM sclm = new SCLM();
Aутентификация
Клиент может взаимодействовать с API StoryCLM в двух режимах:
- От имени сервиса (Service) - используется для интеграции StoryCLM с другой системой. Для аутентификации достаточно только ClientId и Secret. Клиент получает доступ только в рамках клиента StoryCLM в котором ему были выданы учетные данные.
- От имени пользователя StoryCLM (Application) - используется в мобильных или настольных приложениях. Помимо ClientId и Secret для успешной аутентифкации требуются еще Username и Password пользователя. Клиент работает от имени пользователя StoryCLM и, за исключением некоторых разделов API (Таблицы), получает доступ ко всем ресурсам которые доступны пользователю в клиента StoryCLM в которых у него есть права.
Аутентифкация от имени сервиса:
SCLM sclm = new SCLM();
StoryToken token = await sclm.AuthAsync(clientId, secret);
Аутентификация от имени пользователя:
SCLM sclm = new SCLM();
StoryToken token = await sclm.AuthAsync(clientId, secret, username, password);
В случаи успешной аутентификации будет возвращен объект StoryToken. Объект StoryToken имеет следующие поля:
- AccessToken - маркер доступа.
- RefreshToken - маркер обновления. Выдается если клиент работет от имени пользователя.
- Expires - дата истеченя срока маркера доступа.
В случае необходимости StoryToken можно получить из контекста, обратясь к полю "Token".
StoryToken token = sclm.Token;
Практики обновления маркеров доступа
После успешной аутентифкации маркер доступа автоматически сохраняется на все время жизни контекста и автоматически прикрепляется к каждому запросу к серверу. Стоит учитывать, что маркер доступа "живет" один час. После истечения срока действия текущего маркера доступа нужно получуть новый маркер. Этот процесс разнится в зависимости от типа аутентификации и способа интеграции с StoryCLM.
Service - клиент работает от имени сервиса. Если время жизни контекста больше времени жизни маркера доступа, то при каждом следущем обращении сервер будет возвращать код 401. Это означает что клиент не авторизован. Что бы этого не произошло нужно контролировать время жизни маркера доступа и после истечения срока его действия выполнить аутентификацию и получить новый маркер.
Если сессии короткие, то можно сохранять StoryToken между сессиимяи и присваивать его контексту.
SCLM sclm = new SCLM();
StoryToken token = GetToken();
sclm.Token = token;
При таком подходе следует контролировать поле Expires объекта StoryToken что бы выявить момент когда следует обновить маркер.
Лучшей практикой для приложений которые используют подход "Service", будет создавать сесии не больше часа и производить обмен данными с StoryCLM, при этом каждый раз получая новый маркер доступа. Не следует сохранять и хранить маркер доступа в незащищенном хранилище и в открытом виде.
Application - клиент работает от имени пользователя StoryCLM. После аутентификации помимо маркера доступа сервер возвращает маркер обновляения (RefreshToken). Время жизни этого маркера год. Он используется для получения нового маркера доступа без логина и пароля. Это сделано для того что бы каждый раз когда маркер доступа становится просроченым не заставлять пользователя вводить логин и пароль. Контекст автоматически извлекает маркер обновления, контролирует время жизни маркера доступа и самостоятельно получает новые маркеры доступа и обновления. Таким образом контекст может существовать и выполнять успешные запросы к серверу неограниченное колличество времени.
Так же как и с "Service" подходом можно извлекать объект StoryToken, сохранять его и нужный момент использовать. На лучшей практикой будет сохранять только маркер обновления. В таком случае не нужно хранить логин и пароль пользователя, так же маркер обновления можно хранить в отркытом виде. Каждый раз при запуске приложения нужно извлекать из хранилища маркер обновления и выполнить один раз получение нового маркера доступа:
SCLM sclm = new SCLM();
string refreshToken = GetRefreshToken();
await sclm.AuthAsync(clientId, secret, refreshToken);
По завершению работы приложения, нужно сохранть маркер обновления.
Таблицы - это реляционное хранилище данных.
Более подробная информация содержится в разделе "Таблицы" документации.
SDK при работе с таблицами оперирует объектами. Объект должен соответсвовать схеме таблицы. Один объект - одна запись. Создадим таблицу Profiles на панели администрирования и класс Profile в проекте с полями которые будут соответсвовать схеме таблицы Profiles:
/// <summary>
/// Профиль пользователя
/// </summary>
public class Profile
{
/// <summary>
/// Идендификатор записи
/// Зависит от провайдера таблиц
/// </summary>
public string _id { get; set; }
/// <summary>
/// Имя пользователя
/// </summary>
public string Name { get; set; }
/// <summary>
/// Возраст
/// </summary>
public long Age { get; set; }
/// <summary>
/// Пол
/// </summary>
public bool Gender { get; set; }
/// <summary>
/// Рейтинг
/// </summary>
public double Rating { get; set; }
/// <summary>
/// Дата регистрации
/// </summary>
public DateTime Created { get; set; }
}
Описание:
Получает cписок таблиц клиента.
Параметры:
- T - параметризованный тип (generic), описывающий сущность в таблице.
- clientId - Идентификатор клиента в базе данных.
Возвращаемое значение:
Список таблиц
Пример:
SCLM sclm = new SCLM();
await sclm.AuthAsync(clientId, secret);
IEnumerable<StoryTable<Profile>> tables = await sclm.GetTablesAsync<Profile>(clientId);
Описание:
Получает таблицу по идентификатору.
Параметры:
- T - параметризованный тип (generic), описывающий сущность в таблице.
- tableId - Идентификатор таблицы.
Возвращаемое значение:
Объект "Таблица"
Пример:
SCLM sclm = new SCLM();
await sclm.AuthAsync(clientId, secret);
StoryTable<Profile> table = await sclm.GetTableAsync<Profile>(tableId);
Методы GetTablesAsync и GetTablesAsync возвращают типизированные объекты StoryTable<Profile>, в данном случае с типом Profile. Это означает что все операции над данными в этой таблице будут производится с участием этого типа. Для того что бы производить операции с данными таблицы у класса StoryTable есть определенный набор методов.
Описание:
Добавляет новый объект в таблицу. Объект должен соответствовать схеме таблицы.
Параметры:
- o - Новый объект.
Возвращаемое значение:
Новый объект в таблице.
Пример:
SCLM sclm = new SCLM();
await sclm.AuthAsync(clientId, secret);
StoryTable<Profile> table = await sclm.GetTableAsync<Profile>(tableId);
Profile profile = await table.InsertAsync(new Profile());
Описание:
Добавляет коллекцию новых объектов в таблицу. Каждая объект должен соответствовать схеме таблицы.
Параметры:
- o - коллекция новых объектов
Возвращаемое значение:
Коллекция новых объектов.
Пример:
SCLM sclm = new SCLM();
await sclm.AuthAsync(clientId, secret);
StoryTable<Profile> table = await sclm.GetTableAsync<Profile>(tableId);
List<Profile> profiles = new List<Profile>(await table.InsertAsync(Profile.CreateProfiles()));
Описание:
Обновляет объект в таблице. Идентификатор записи остается неизменным.
Параметры:
- o - обновляемый объект.
Возвращаемое значение:
Обновленный объект.
Пример:
SCLM sclm = new SCLM();
await sclm.AuthAsync(clientId, secret);
StoryTable<Profile> table = await sclm.GetTableAsync<Profile>(tableId);
Profile updatedProfile = await table.UpdateAsync(Profile.UpdateProfile(profile));
Описание:
Обновляет коллекцию объектов в таблице. Идентификатор записи остается неизменным.
Параметры:
- o - коллекция обновляемых объектов.
Возвращаемое значение:
Коллекция обновленных объектов.
Пример:
SCLM sclm = new SCLM();
await sclm.AuthAsync(clientId, secret);
StoryTable<Profile> table = await sclm.GetTableAsync<Profile>(tableId);
List<Profile> updatedProfiles = new List<Profile>(await table.UpdateAsync(Profile.UpdateProfiles(profiles)));
Описание:
Удаляет объект таблицы по идентификатору.
Параметры:
- id - Идентификатор записи.
Возвращаемое значение:
Удаленный объект.
Пример:
SCLM sclm = new SCLM();
await sclm.AuthAsync(clientId, secret);
StoryTable<Profile> table = await sclm.GetTableAsync<Profile>(tableId);
Profile deleteResult = await table.DeleteAsync(profile._id);
Описание:
Удаляет коллекцию объектов таблицы по поллекции идентификаторов.
Параметры:
- ids - коллекция идентификаторов.
Возвращаемое значение:
Коллекция удаленных объектов.
Пример:
SCLM sclm = new SCLM();
await sclm.AuthAsync(clientId, secret);
StoryTable<Profile> table = await sclm.GetTableAsync<Profile>(tableId);
IEnumerable<Profile> deleteResults = await table.DeleteAsync(profiles.Select(t=> t._id));
Описание:
Получает колличество записей в таблице.
Возвращаемое значение:
Колличество записей.
Пример:
SCLM sclm = new SCLM();
await sclm.AuthAsync(clientId, secret);
StoryTable<Profile> table = await sclm.GetTableAsync<Profile>(tableId);
long count = await table.CountAsync(tableId);
Описание:
Получает колличество записей в таблице по запросу. Запрос должен быть в формате TablesQuery.
Параметры:
- query - запрос в формате TablesQuery
Возвращаемое значение:
Колличество записей.
Пример:
SCLM sclm = new SCLM();
await sclm.AuthAsync(clientId, secret);
StoryTable<Profile> table = await sclm.GetTableAsync<Profile>(tableId);
long count = await table.CountAsync("[age][gt][30]");
Описание:
Получает колличество записей лога таблицы.
Возвращаемое значение:
Колличество записей.
Пример:
SCLM sclm = new SCLM();
await sclm.AuthAsync(clientId, secret);
StoryTable<Profile> table = await sclm.GetTableAsync<Profile>(tableId);
long count = await table.LogCountAsync();
Описание:
Получает колличество записей лога после указанной даты.
Параметры:
- date - Дата, после которой будет произведена выборка.
Возвращаемое значение:
Колличество записей.
Пример:
SCLM sclm = new SCLM();
await sclm.AuthAsync(clientId, secret);
StoryTable<Profile> table = await sclm.GetTableAsync<Profile>(tableId);
long count = await table.LogCountAsync((DateTime.Now.AddDays(-25)));
Описание:
Получает записи лога.
Параметры:
- skip - Отступ в запросе. Сколько первых элементов нужно пропустить. По умолчанию - 0.
- take - Максимальное количество записей, которые будут получены. По умолчанию - 100, максимально 1000.
Возвращаемое значение:
Коллекция записей лога.
Пример:
SCLM sclm = new SCLM();
await sclm.AuthAsync(clientId, secret);
StoryTable<Profile> table = await sclm.GetTableAsync<Profile>(tableId);
IEnumerable<ApiLog> = await table.LogAsync(0, 1000);
Описание:
Получает записи лога, после указаной даты.
Параметры:
- date - Дата, после которой будет произведена выборка.
- skip - Отступ в запросе. Сколько первых элементов нужно пропустить. По умолчанию - 0.
- take - Максимальное количество записей, которые будут получены. По умолчанию - 100, максимально 1000.
Возвращаемое значение:
Коллекция записей лога.
Пример:
SCLM sclm = new SCLM();
await sclm.AuthAsync(clientId, secret);
StoryTable<Profile> table = await sclm.GetTableAsync<Profile>(tableId);
IEnumerable<ApiLog> = await table.LogAsync(DateTime.Now.AddDays(-25), 0, 1000);
Описание:
Получает запись таблицы по идентификатору.
Параметры:
- id - Идентификатор записи.
Возвращаемое значение:
Объект в таблице.
Пример:
SCLM sclm = new SCLM();
await sclm.AuthAsync(clientId, secret);
StoryTable<Profile> table = await sclm.GetTableAsync<Profile>(tableId);
Profile profile = await table.FindAsync(id);
Описание:
Получает коллекцию записей по списку идентификаторов.
Параметры:
- ids - коллекция идентификаторов.
Возвращаемое значение:
Коллекция объектов.
Пример:
SCLM sclm = new SCLM();
await sclm.AuthAsync(clientId, secret);
StoryTable<Profile> table = await sclm.GetTableAsync<Profile>(tableId);
IEnumerable<Profile> profiles = await table.FindAsync(ids);
Описание:
Получает постранично все данные таблицы.
Параметры:
- skip - Отступ в запросе. Сколько первых элементов нужно пропустить. По умолчанию - 0.
- take - Максимальное количество записей, которые будут получены. По умолчанию - 100, максимально 1000.
Возвращаемое значение:
Коллекция объектов.
Пример:
SCLM sclm = new SCLM();
await sclm.AuthAsync(clientId, secret);
StoryTable<Profile> table = await sclm.GetTableAsync<Profile>(tableId);
IEnumerable<Profile> profiles = await table.FindAsync(0, 1000);
Method: Task<IEnumerable<T>> FindAsync(string query, string sortfield, int sort, int skip, int take)
Описание:
Получает постранично данные по запросу. Формат запроса - TablesQuery.
TablesQuery - это язык запросов, разработанного специально для StoryCLM. Запрос в данном формате легко транслируется в любы другие языки запросов.
Параметры из которых создается запрос могут быть двух типов: Comparison и Logical.
Параметры:
- query - Запрос в формате TablesQuery.
- sortfield - Поле, по которому нужно произвести сортировку.
- sort - Тип сортировки.
- tableId - Идентификатор таблицы в базе данных.
- skip - Отступ в запросе. Сколько первых элементов нужно пропустить. По умолчанию - 0.
- take - Максимальное количество записей, которые будут получены. По умолчанию - 100, максимально 1000.
Возвращаемое значение:
Коллекция объектов.
Пример:
SCLM sclm = new SCLM();
await sclm.AuthAsync(clientId, secret);
StoryTable<Profile> table = await sclm.GetTableAsync();
//возраст меньше или равен 30
IEnumerable<Profile> profiles = await table.FindAsync("[age][lte][30]", "age", 1, 0, 100);
//поле "name" начинается с символа "T"
profiles = await table.FindAsync("[name][sw][\"T\"]", "age", 1, 0, 100);
//поле "name" содержит строку "ad"
profiles = await table.FindAsync("[Name][cn][\"ad\"]", "age", 1, 0, 100);
//поиск имен из списка
profiles = await table.FindAsync("[Name][in][\"Stanislav\",\"Tamerlan\"]", "age", 1, 0, 100);
//Выбрать женщин, имя ("name") которых начинается со строки "V"
profiles = await table.FindAsync("[gender][eq][false][and][Name][sw][\"V\"]", "age", 1, 0, 100);
//Выбрать мужчин младше 30 и женщин старше 30
profiles = await table.FindAsync("[gender][eq][true][and][age][lt][30][or][gender][eq][false][and][age][gt][30]", "age", 1, 0, 100);
//поле "name" начинается с символов "T" или "S" при этом возраст должен быть равен 22
profiles = await table.FindAsync("([name][sw][\"S\"][or][name][sw][\"T\"])[and][age][eq][22]", "age", 1, 0, 100);
//Выбрать всех с возрастом НЕ в интервале [25,30] и с именами на "S" и "Т"
profiles = await table.FindAsync("([age][lt][22][or][age][gt][30])[and]([name][sw][\"S\"][or][name][sw][\"T\"])", "age", 1, 0, 100);
Описание:
Возвращается максимальное значение.
Параметры:
- T - тип поля.
- field - Название поля.
- query - Запрос в формате TablesQuery.
Возвращаемое значение:
Максимальное значение.
Пример:
SCLM sclm = new SCLM();
await sclm.AuthAsync(clientId, secret);
StoryTable<Profile> table = await sclm.GetTableAsync<Profile>(tableId);
bool boolResult = await storyTable.MaxAsync<bool>("Gender");
int intResult = await storyTable.MaxAsync<int>("Age");
string stringResult = await storyTable.MaxAsync<string>("Name");
DateTime datetimeResult = await storyTable.MaxAsync<DateTime>("Created");
double doubleResult = await storyTable.MaxAsync<double>("Rating");
bool boolQueryResult = await storyTable.MaxAsync<bool>("Gender", "[Gender][eq][false]");
int intQueryResult = await storyTable.MaxAsync<int>("Age", "[Gender][eq][false]");
string stringQueryResult = await storyTable.MaxAsync<string>("Name", "[Gender][eq][false]");
DateTime datetimeQueryResult = await storyTable.MaxAsync<DateTime>("Created", "[Gender][eq][false]");
double doubleQueryResult = await storyTable.MaxAsync<double>("Rating", "[Gender][eq][false]");
Описание:
Возвращается минимальное значение.
Параметры:
- T - тип поля.
- field - Название поля.
- query - Запрос в формате TablesQuery.
Возвращаемое значение:
Максимальное значение.
Пример:
SCLM sclm = new SCLM();
await sclm.AuthAsync(clientId, secret);
StoryTable<Profile> table = await sclm.GetTableAsync<Profile>(tableId);
bool boolResult = await storyTable.MinAsync<bool>("Gender");
int intResult = await storyTable.MinAsync<int>("Age");
string stringResult = await storyTable.MinAsync<string>("Name");
DateTime datetimeResult = await storyTable.MinAsync<DateTime>("Created");
double doubleResult = await storyTable.MinAsync<double>("Rating");
bool boolQueryResult = await storyTable.MinAsync<bool>("Gender", "[Gender][eq][false]");
int intQueryResult = await storyTable.MinAsync<int>("Age", "[Gender][eq][false]");
string stringQueryResult = await storyTable.MinAsync<string>("Name", "[Gender][eq][false]");
DateTime datetimeQueryResult = await storyTable.MinAsync<DateTime>("Created", "[Gender][eq][false]");
double doubleQueryResult = await storyTable.MinAsync<double>("Rating", "[Gender][eq][false]");
Описание:
Возвращает сумму.
Параметры:
- T - тип поля.
- field - Название поля.
- query - Запрос в формате TablesQuery.
Возвращаемое значение:
Сумма.
Пример:
SCLM sclm = new SCLM();
await sclm.AuthAsync(clientId, secret);
StoryTable<Profile> table = await sclm.GetTableAsync<Profile>(tableId);
bool boolSumResult = await storyTable.SumAsync<bool>("Gender");
long intSumResult = await storyTable.SumAsync<long>("Age");
double doubleSumResult = await storyTable.SumAsync<double>("Rating");
bool boolQuerySumResult = await storyTable.SumAsync<bool>("Gender", "[Gender][eq][true]");
int intQuerySumResult = await storyTable.SumAsync<int>("Age", "[Gender][eq][true]");
double doubleQuerySumResult = await storyTable.SumAsync<double>("Rating", "[Gender][eq][false]");
Описание:
Возвращает среднее занчение.
Параметры:
- T - тип поля.
- field - Название поля.
- query - Запрос в формате TablesQuery.
Возвращаемое значение:
Среднее значение.
Пример:
SCLM sclm = new SCLM();
await sclm.AuthAsync(clientId, secret);
StoryTable<Profile> table = await sclm.GetTableAsync<Profile>(tableId);
double intAvgResult = await storyTable.AvgAsync("Age");
double doubleAvgResult = await storyTable.AvgAsync("Rating");
double intQueryAvgResult = await storyTable.AvgAsync("Age", "[Gender][eq][true]");
double doubleQueryAvgResult = await storyTable.AvgAsync("Rating", "[Gender][eq][false]");
Описание:
Возвращает первый элемент или null.
Параметры:
- query - Запрос в формате TablesQuery.
- sortfield - Поле, по которому нужно произвести сортировку.
- sort - Тип сортировки.
Возвращаемое значение:
Объект.
Пример:
SCLM sclm = new SCLM();
await sclm.AuthAsync(clientId, secret);
StoryTable<Profile> table = await sclm.GetTableAsync<Profile>(tableId);
Profile profile = await storyTable.FirstAsync("[Age][eq][33]", "age", 1);
Profile profile1 = await storyTable.FirstAsync(sortfield: "age", sort: 1);
Profile profile2 = await storyTable.FirstAsync(sortfield: "age");
Profile profile3 = await storyTable.FirstAsync();
Описание:
Возвращает последний объект или null.
Параметры:
- query - Запрос в формате TablesQuery.
- sortfield - Поле, по которому нужно произвести сортировку.
- sort - Тип сортировки.
Возвращаемое значение:
Объект.
Пример:
SCLM sclm = new SCLM();
await sclm.AuthAsync(clientId, secret);
StoryTable<Profile> table = await sclm.GetTableAsync<Profile>(tableId);
Profile profile4 = await storyTable.LastAsync("[Age][eq][22]", "age", 1);
Profile profile5 = await storyTable.LastAsync(sortfield: "age", sort: 1);
Profile profile6 = await storyTable.LastAsync(sortfield: "age");
Profile profile7 = await storyTable.LastAsync();