Interfaces

Источник данных — это объект с CRUD + архитектурой, предоставляющий доступ к типовым операциям (create, read, update, delete, ...), применяемым к объекту предметной области (сущности).

Задачи источников:

  • обеспечение получения данных с широкого спектра хранилищ;
  • порождение сущностей Model и DataSet, содержащих данные из хранилища.

Интерфейс источника данных

Интерфейс источника данных определяет набор операций, выполняемых с данными.

Реализован в Types/source:ICrud и Interface Types/source:ICrudPlus — интерфейс источника данных, поддерживающего расширенный контракт CRUD — операции merge, copy и move.

Список операций:

  • create — создать модель (при этом она не сохраняется в хранилище);
  • read — прочитать модель по первичному ключу;
  • update — обновить модель;
  • destroy — удалить модель по первичному ключу;
  • merge — объединить две модели;
  • copy — скопировать модель;
  • query — получить список моделей по запросу;
  • call — вызвать метод (только для RPC источников).

Термины

  • провайдер — объект, предоставляющий доступ к хранилищу данных определенного вида. Зачастую это реализация стандартной технологии и/или протокола (например, HTTP, RESTful, JSON-RPC, XML-RPC, SOAP);
  • хранилище данных — программно-аппаратный комплекс, предоставляющий API для удаленного получения данных. Должен работать по протоколу, используемому провайдером;
  • endpoint (конечная точка) — настройка, обеспечивающая доступ клиента к функциональным возможностям источника данных. Минимальными настройками конечной точки являются адрес подключения и имя (или адрес) сущности. Если протокол взаимодействия требует дополнительных настроек (например, идентификации клиента при подключении), то спецификация конечной точки расширяется;
  • binding (привязка) — настройка, определяющая соответствие методов CRUD+ контракту. Определяет, как именно конкретный источник реализует каждый метод CRUD+.

Типовые виды хранилищ:

  • обертка вокруг СУБД, например LAMP;
  • специализированный веб-сервис;
  • локальный сервис, например localStorage.

Если хранилище данных находится за уровнем приложения, то провайдер должен использовать различные варианты стека протоколов OSI для передачи данных (например, HTTP (XHR), WebSocket).

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

Уровни абстракции

Интерфейс включает в себя следующие виды абстракций:

  • абстракция доступа к хранилищу;
  • абстракция подключения;
  • абстракция привязки.

Диаграмма уровней абстракции доступа

  • Data Source — источник данных;
  • Provider — провайдер доступа к хранилищу;
  • Storage — хранилище данных, предоставляющее определенное API.

Абстракция доступа позволяет работать с разными видами хранилищ, находящихся на разных уровнях сетевой модели (либо доступными без сетевого подключения).

Диаграмма уровней абстракции подключения

  • Data Source — источник данных;
  • Endpoint — конечная точка.

Абстракция подключения позволяет одинаково конфигурировать хранилища разного API и архитектуры:

  • для key-value хранилища — сформировать префиксы ключей;
  • для простого веб-сервиса — сформировать базовый URL для обращения;
  • для RPC-сервиса — сформировать адрес подключения и пространство имен методов (либо их префикс);
  • для SOAP — сформировать адрес WSDL и пространство имен методов;
  • для реляционной базы данных — сформировать адрес подключения, имя базы данных и имя основной таблицы сущности;
  • для ORM — сформировать адрес подключения, имя сущности.

Диаграмма уровней абстракции привязки

  • Data Source — источник данных;
  • Binding — привязка.

Абстракция привязки позволяет одинаково работать с любой инфраструктурой сущностей в формате CRUD+:

  • для простого веб-сервиса — сформировать URL для каждой операции CRUD+;
  • для RPC-сервиса — вызвать конкретный метод;
  • для реляционной базы данных — сформировать SQL запрос;
  • для ORM — вызвать метод сущности.

Примеры

Подключим абстрактный источник, работающий c сущностью "Пользователь" через HTTP:

var dataSource = new HttpSource({
   endpoint: {
      address: '//api.server.name/',
      contract: 'user/'
   },
   binding: {
      create: 'add/', // dataSource.create() вызовет //api.server.name/user/add/
      read: 'load/', // dataSource.read() вызовет //api.server.name/user/load/
      update: 'save/', // dataSource.update() вызовет //sapi.server.name/user/save/
      destroy: 'delete/', // dataSource.destroy() вызовет //api.server.name/user/delete/
      query: 'list/' // dataSource.query() вызовет //api.server.name/user/list/
   }
});

Подключим абстрактный источник, работающий c сущностью "Пользователь" через RPC:

var dataSource = new RpcSource({
   endpoint: {
      address: '//api.server.name/',
      contract: 'User'
   },
   binding: {
      create: 'Add', // dataSource.create() вызовет UserAdd()
      read: 'Load', // dataSource.read() вызовет UserLoad()
      update: 'Save', // dataSource.update() вызовет UserSave()
      destroy: 'Delete', // dataSource.destroy() вызовет UserDelete()
      query: 'List' // dataSource.query() вызовет UserList()
   }
});

Types/source:Memory

Memory — источник данных, получающий данные из оперативной памяти.

Ограничения

  • не требует настройки endpoint и binding;
  • не хранит данные между перезапусками приложения (перезагрузка страницы).

Важно

По умолчанию используется адаптер для данных в формате JSON.

Если вы используете данные в каком-либо другом формате (СБИС-JSON, XML), то нужно подключить соответствующий адаптер.

Примеры

Создадим источник с данными объектов солнечной системы:

var solarSystem = new MemorySource({
   data: [
      {id: 1, name: 'Sun', kind: 'Star'},
      {id: 2, name: 'Mercury', kind: 'Planet'},
      {id: 3, name: 'Venus', kind: 'Planet'},
      {id: 4, name: 'Earth', kind: 'Planet'},
      {id: 5, name: 'Mars', kind: 'Planet'},
      {id: 6, name: 'Jupiter', kind: 'Planet'},
      {id: 7, name: 'Saturn', kind: 'Planet'},
      {id: 8, name: 'Uranus', kind: 'Planet'},
      {id: 9, name: 'Neptune', kind: 'Planet'},
      {id: 10, name: 'Pluto', kind: 'Dwarf planet'}
   ],
   keyProperty: 'id'
});

Получим данные о Земле:

solarSystem.read(4).addCallback(function(planet) {
    planet.get('name'); // 'Earth'
});

Получим список планет:

var query = new Query();
query.where({
    kind: 'Planet'
});
solarSystem.query(query).addCallback(function(dataSet) {
    var planets = dataSet.getAll();
    planets.getCount(); // 8
    planets.each(function(planet) {
       console.log(planet.get('name'));
    });
    // output: Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
});

Types/source:SbisService

SbisService — источник данных, работающий с БЛ СБИС.

Использует адаптер для данных в формате СБИС-JSON.

Примеры

Создадим источник для объекта БЛ "Сотрудники":

var dataSource = new SbisService({
   endpoint: 'Staff',
   keyProperty: '@СвязиПользователя'
});

Создадим источник для объекта БЛ "Сотрудники" c отдельной точкой входа:

var dataSource = new SbisService({
   endpoint: {
      address: '/service/staff/',
      contract: 'Staff'
   },
   keyProperty: '@СвязиПользователя'
});

Создадим источник для объекта БЛ "Сотрудники" с указанием нестандартного метода получения выборки:

var dataSource = new SbisService({
   endpoint: 'Staff',
   binding: {
      query: 'List'
   },
   keyProperty: '@СвязиПользователя'
});

Получим данные о сотруднике:

dataSource.read([123454321]).addCallback(function(employee) {
    employee.get('Фамилия');
});

Получим список сотрудников с фамилией Иванов:

var query = new Query();
query.where({
    Фамилия: 'Иванов'
});
dataSource.query(query).addCallback(function(dataSet) {
    var employees = dataSet.getAll();
    employees.getCount();
    employees.each(function(employee)) {
       console.log(employee.get('Имя'));
    });
});

Диаграмма классов

См. также