Rest API Вступ - datawizio/pythonAPI GitHub Wiki

Datawiz Business Intelligent Application Program Interface v.1

Сервіс Datawiz BI розміщений в мережі Інтернет і пропонує послуги аналізу рітейл-даних, які надають клієнти компанії. Для успішної роботи сервісу необхідно завантажити на нього стартові дані (касові чеки і деякі довідники) за порівняно великий період (рік чи більше), а опісля щоденно поповнювати його новими даними. Саме для цього застосовується Програмний інтерфейс взаємодії (скорочено - API - Application Program Interface) "Datawiz BI API v.1."

Схема взаємодії програмного забезпечення клієнта із сервісом Datawiz BI являє собою класичну схему "Клієнт-сервер". Де в ролі сервера виступає сервіс "Datawiz BI", а в ролі клієнта - програмне забезпечення клієнта сервісу. З цього можна легко уявити собі основні елементи взаємодії цих двох систем:

  1. Клієнт звертається до сервера і встановлює з'єднання
  2. Клієнт відправляє на сервер запит з даними
  3. Сервер повертає відповідь з даними чи кодом помилки
  4. З'єднання розривається

Тепер про реалізацію. Datawiz BI API v.1 побудований з використанням технології [REST] (http://uk.wikipedia.org/wiki/REST), що значно спрощує процес взаємодії клієнта і сервера. Далі будемо називати Datawiz BI API скорочено: REST API і познайомимось з його основними елементами:

Короткий опис REST API:

Ресурси

REST API для забезпечення взаємодії сервера і клієнта використовує стандартний HTTP-протокол. Згідно до цього протоколу вся інформація, яка зосереджена в мережі, називається ресурсами. Кожен такий ресурс має свій унікальний уніфікований локатор ресурсу (Unified Resource Locator - [URL] (http://uk.wikipedia.org/wiki/URL)) - адрес, з допомогою якого можна чітко ідентифікувати той чи інший ресурс.

Приклад ресурсу: http://api.datawiz.io/api/v1/ - вказує на кореневий елемент REST API v.1 сервісу [datawiz BI] (http://api.datawiz.io)

Як видно, ресурс схожий на шлях файлової системи, яка вказує на об'єкт у середині себе. Якщо уважно розібратись, то можна побачити: кореневий каталог - //; перший рівень - доменне ім'я (api.datawiz.io); далі слідує ім'я кореневого каталогу (api) на сервері, наступний рівень - його уточнення (v1) і т.д...

Команди

Взаємодія клієнта і сервера, в термінах HTTP-протоколу розпочинається із відправлення запиту клієнтом на сервер. При цьому клієнт передає на сервер заголовок і тіло запиту, в заголовку вказується команда та інші необхідні параметри, в тілі запиту направляється рівень (в JSON форматі), який необхідно додати чи замінити на сервері. В результаті взаємодії клієнта із сервером клієнт отримує відповідь сервера (заголовок і тіло), в яких сервер передає HTTP-код відповіді та дані (в JSON форматі). Далі цикл взаємодії клієнта і сервера повторюється.

Для управління ресурсами використовується стандартний набір команд HTTP-протоколу:

Команда Опис
GET для отримання інформації з сервера
POST для додавання інформації на сервер
PUT для внесення змін (модифікацій) інформації на сервері
PATCH для вибіркової зміни інформації (наприклад, не цілого об'єкта, а тільки окремих його полів)
DELETE для видалення інформації з сервера
OPTIONS отримання мета-інформації про ресурс
HEAD аналог GET, тільки із сервера повертається один заголовок, без тіла

Формат даних

Об'єкти в тілі запиту надаються в визначеному форматі. Найпопулярнішим форматами подання структурної інформації в REST API є [JSON] (http://uk.wikipedia.org/wiki/JSON), [XML] (http://uk.wikipedia.org/wiki/XML), [HTML] (http://uk.wikipedia.org/wiki/HTML). Datawiz BI API v.1 використовує формат JSON для взаємодії додатків та HTML для презентаційного представлення API за адресою: http://api.datawiz.io/api/.

Приклад відповіді сервера в форматі JSON на запит клієнта GET http://api.datawiz.io/api/.json:

{
     "v1": "http://api.datawiz.io/api/v1/", 
     "v2": "not available yet" 
}

Вибір формату даних лежить на клієнті. І зробити це він може декількома способами (представлено в порядку зменшення пріоритету):

  1. Формат даних можна вказати в виді суфікса URL: .json (JSON) чи .api (HTML). Див. попередній приклад.
  2. Формат даних можна вказати в виді додаткового параметра format:?Format=json чи ?Format=api. Якщо одночасно вказані і суфікс і параметр, то перевага надаватиметься суфіксу. Приклад: http://api.datawiz.io/api/?Format=api.
  3. Формат даних можна вказати в заголовку HTTP Content-Type вказавши application/json чи application/html. Цей спосіб вибору формату діє тільки тоді, коли відсутні інші способи вибору формату.
  4. По домовленості, якщо ні один із вищевказаних способів вибору формату не представлений, вибирається формат JSON.

РЕСУРСИ REST API:

Ресурси REST API представлені двома видами:

  • колекції
  • об'єкти

Колекції

Колекції - це списки об'єктів. Колекції представляються в виді масивів JSON та використовуються для відправлення на сервер чи отримання із сервера відразу декількох об'єктів за один запит. Заключний елемент колекції (endpoint) - це завжди назва ресурсу.

Приклад ресурсів типу "колекція":

  • /Products/ - отримати перші 10 елементів із довідника по товарах чи відправити вказану клієнтом кількість товарів на сервер
  • /Receipts/ - отримати із сервера перші 10 чеків або відправити вказану клієнтом кількість чеків на сервер
  • /Receipts/1-1_20141120195527_297/cartitems/ - отримати список (колекцію) всіх покупок із чека з id=1-1_20141120195527_297

Параметри управління колекціями, які отримуємо із сервера.

Колекції можуть містити в собі від нуля до декількох десятків і навіть сотень тисяч елементів. Отримання всіх цих елементів за один запит може сильно перевантажити сервер, мережу та клієнтське програмне забезпечення, тому виникає необхідність у дозованому отриманні необхідної інформації із сервера.

Таким способом є "гортання" колекцій (pagenating). Під "гортанням" розуміють розбивання колекції на сторінки і вивантаженням за один запит всього однієї такої сторінки.

Для управління "гортанням" колекцій використовуються додаткові параметри URL:

Параметр Допомога
page_size розмір сторінки. За замовчуванням, якщо цей параметр не вказаний, розмір сторінки - 10 елементів)
page номер сторінки. За замовчуванням, якщо цей параметр не вказаний, вивантажуються перші page_size елементи, тобто за замовчуванням - page = 1.

Структура колекції

Для легкого управління колекціями (в тому числі, для управління "гортанням") кожна колекція повертає клієнту JSON-словник, в якому представлені 4 параметри:

  • Count - загальна кількість об'єктів у колекції
  • Next - вказівник (url) на наступну "сторінку" даних у колекції
  • Previous - вказівник (url) на попередню"сторінку" даних у колекції
  • Results - масив об'єктів даної сторінки. К-сть елементів у масиві завжди менша чи рівна page_size.

Приклад відповіді сервера на запит: "Повернути колекцію із 2 записів із довідника по товарах в форматі json":

GET http://api.datawiz.io/api/v1/products/?Format=json&page_size=2:

{
     "count": 24880, 
     "next": "http://api.datawiz.io/api/v1/products/?page=2&page_size=2&format=json", 
     "previous": null, 
     "results": [
         {
             "url": "http://api.datawiz.io/api/v1/products/17786/", 
             "product_id": "17786", 
             "name": "\" La Festa \ "Капучіно GV 12,5 * 10 * 8шт (нат/розч) (вершки" 
         } 
         {
             "url": "http://api.datawiz.io/api/v1/products/17785/", 
             "product_id": "17785", 
             "name": "\" La Festa \ "Капучіно GV 12,5х10х8шт (нат/розч) горіх" 
         } 
     ] 
}

Управління колекціями, які відправляють на сервер

Клієнт керує колекціями об'єктів, які відправляють на сервер. Також він вибирає спосіб передачі даних на сервер - по-одинці чи списком. Тут потрібно звернути увагу на наступне: передача даних поодинці - повільний процес, і використовується тоді, коли необхідно додати чи замінити один-два об'єкти, тоді як передача списком значно пришвидшує процес передачі даних на сервер, але ускладнює контроль над визначеними об'єктами. Крім того потрібно пам'ятати, що сервер має обмеження на розмір даних, що передаються (близько 200Кб ~ 2000 об'єктів), тому при необхідності дані на сервер потрібно передавати частинами.

Об'єкти

Об'єкти - це структури даних, представлені у виді словників JSON, в яких ключовими словами (ключами) є назви полів, а даними - значення цих полів. Поля можуть вказувати на вкладені структури (словники та масиви), таким чином будується складна структура об'єкта. Отримати інформацію про структурі об'єкта можна, відправивши на сервер запит OPTIONS. Заключний елемент об'єкта (endpoint) - це завжди ідентифікатор ресурсу.

Приклад ресурсів типу "об'єкт":

  • /Products/*12345* - взаємодіяти з визначеним елементом із довідника по товарах з id = 12345
  • /Receipts/*12345* - отримати доступ до чека з id=12345
  • /Receipts/*12345*/cartitems/*1* - прочитати перший рядок в чеку з id = 12345

Приклад відповіді сервера на запит: "Повернути запис із довідника по товарах з id=77087-24316 в форматі json": GET http://api.datawiz.io/api/v1/products/77087-24316/.json:

{
    "url": "http://api.datawiz.io/api/v1/products/77087-24316/", 
    "product_id": "77087-24316", 
    "name": ". баликова н/к 1с. (ш/о/б) вак . (кг)", 
    "category_id": "79", 
    "category_url": "http://api.datawiz.io/api/v1/categories/79/", 
    "unit_id": "3-1-0", 
    "unit_url": "http://api.datawiz.io/api/v1/units/3-1-0/"
}

Якщо замість GET вказати OPTIONS, то для вищевказаного запиту будемо мати опис структури вищевказаного запиту:

OPTIONS http://api.datawiz.io/api/v1/products/77087-24316/.json

HTTP 200 OK
Content-Type: application/json
Vary: Accept
Allow: GET, PUT, DELETE, HEAD, OPTIONS, PATCH
{
    "name": "Product Instance", 
    "description": "Об'єкт 'Товар' призначений для зберігання інформації про товар", 
    "renders": [
        "application/json", 
        "text/html"
    ], 
    "parses": [
        "application/json", 
        "application/x-www-form-urlencoded", 
        "multipart/form-data"
    ], 
    "actions": {
        "PUT": {
            "url": {
                "type": "field", 
                "required": false, 
                "read_only": true
            }, 
            "product_id": {
                "type": "string", 
                "required": true, 
                "read_only": false, 
                "max_length": 100
            }, 
            "name": {
                "type": "string", 
                "required": true, 
                "read_only": false, 
                "label": "name", 
                "max_length": 200
            }, 
            "category_id": {
                "type": "string", 
                "required": true, 
                "read_only": false, 
                "max_length": 100
            }, 
            "category_url": {
                "type": "field", 
                "required": false, 
                "read_only": true
            }, 
            "unit_id": {
                "type": "string", 
                "required": true, 
                "read_only": false, 
                "max_length": 50
            }, 
            "unit_url": {
                "type": "field", 
                "required": false, 
                "read_only": true
            }
        }
    }
}

Опис структури, призначений по запиту OPTIONS дозволяє зрозуміти, які дані ми можемо отримати із сервера, чи які дані необхідно підготувати для внесення змін на сервері. Наприклад, аналізуючи параметри required і read_only зрозуміло, які поля можна модифікувати і які з них обов'язкові до заповнення.

Із вищевказаного результату команди OPTIONS бачимо, що для реєстрації нового товару в довіднику по товарах необхідно та достатньо заповнити 4 обов'язкових поля: product_id, name, category_id і unit_id. Неважко здогадатись, що поля category_id та unit_id - ідентифікатори із довідників "Категорії товарів" та "Одиниці виміру".

Ідентифікатори ресурсів (поле url)

Для надійної ідентифікації ресурсів та пов'язання їх між собою використовуються ідентифікатори об'єктів. Ідентифікатори об'єктів являють собою URL, записані в полі url. За необхідності для завантаження даних із пов'язаного об'єкта достатньо прочитати вміст поля url та використати його в GET-запиті. Поля url є полями "тільки для читання", тому при передачі об'єктів на сервер їх заповнювати не потрібно.

Тестова платформа

Для кращого розуміння структури REST API та команд, які він надає, можна скористатись тестовою платформою за адресою http://api.datawiz.io/api/. Отримати доступ до нього можна, вказавши ім'я клієнта та пароль, які використовуються для входу в веб-інтерфейс ресурсу http://api.datawiz.io

Авторизація доступу

На даний момент REST API підтримуються 2 моделі авторизації:

  1. OAuth v2 - з допомогою імені та пароля
  2. Авторизації на базі підпису (HTTP Signature Authentication)

Довідник ресурсів REST API

Тепер, давайте ознайомимося із ресурсами REST API. Всього REST API надає доступ до 8 ресурсів:

  1. Shops - список магазинів клієнта (тільки читання)
  2. Terminals - список касових терміналів для кожного з магазинів
  3. Categories - ієрархічний список категорій товарів
  4. Units - одиниці виміру
  5. Products - номенклатура (список товарів)
  6. Loyalty - програма лояльності
  7. Cashiers - список касирів
  8. Receipts/Cartitems - чеки

Ресурси з п.1 по п.7 є довідниками і необхідні для правильного подання інформації з п.8 Чеки.

Всі ресурси пов'язані одне з одним. От короткий опис зв'язків:

  1. Користувач сервісу (Client) може змінити декілька магазинів (Client->Shops). Але не менше одного. - Зв'язок "Один до багатьох"
  2. Магазин (Shop) може мати декілька касових терміналів (Shop->Terminals). Але не менше одного. - Зв'язок "Один до багатьох"
  3. Список категорій товарів (Categories) - ієрархічна структура. Ієрархія створюється з допомогою поля parent_id, в яке записується ідентифікатор батьківської категорії. Кореневий елемент ієрархії один, для якого parent_id не визначений (пустий) і містить в полі "Найменування категорії" ім'я користувача сервісу (перший рівень ієрархії); Категорії другого рівня представляють вершину ієрархії категорій товарів
  4. Одиниці виміру (Units) можуть бути цілими (їх можна порахувати) (шт.) і дробовими (їх можна розділити на частини) (кг.). Також одиниці виміру можуть бути упаковками (ящ. 12 шт.)
  5. Номенклатура (список товарів) (Products) містить найменування товарів. Кожен товар зв'язаний (зв'язок 1:1) до одиниці виміру (Product->Unit) і до категорії товару (Product->Category) (зв'язок 1:1). І в першому, і в другому варіанті зв'язки повинні бути визначені.
  6. Програма лояльності (Loyalty) - дані про клієнта-учасника програми лояльності (ід.карточки клієнта, ім'я, день народження...)
  7. Список касирів (Cashiers) - глобальний список (не прив'язаний до конкретного магазину) всіх касирів (ідентифікатор, ім'я)
  8. Чеки. (Receipts) - список чеків. Центральний елемент всієї структури. Кожен чек ідентифікується сукупністю полів: "Дата чека" (date) + "Касовий термінал" (terminal) + "Ідентифікатор чека" (check_id) і має такі зв'язки:
  • Receipt->Shop (зв'язок 1:1) - чек прив'язаний до Магазину. Зв'язок має бути визначеним
  • Receipt->Terminal (зв'язок 1:1) - чек прив'язаний до конкретного касового терміналу. Зв'язок має бути визначеним
  • Receipt->Cashier (зв'язок 1:1) - чек МОЖЕ БУТИ прив'язаний до касира. Цей зв'язок МОЖЕ бути НЕ ВИЗНАЧЕНИМ
  • Receipt->Loyalty (зв'язок 1:1) - чек МОЖЕ БУТИ прив'язаний до програми лояльності (вказує на клієнта, який здійснив покупку). Цей зв'язок МОЖЕ бути НЕ ВИЗНАЧЕНИМ
  • Receipt->Cartitems (зв'язок 1:N) - чек МІСТИТЬ 0 чи більше "Позицій товарів" (Cartitems). Кожна позиція (Cartitem) вказує на товар із "Списку номенклатури" (Product) (зв'язок 1:1) (зв'язок має бути визначеним), містить ціну за одиницю товару, кількість та загальну ціну позиції. ПРИМІТКА: Cartitems розглядається не як окремий ресурс, а як частина Чека (Receipt).

Перелік основних ресурсів REST API можна знайти за адресою http://api.datawiz.io/api/v1/. Виконавши запит до цього ресурсу отримаємо наступний JSON-об'єкт типу словник (dictionary): Запит: GET http://api.datawiz.io/api/v1

HTTP 200 OK
Content-Type: application/json
Vary: Accept
Allow: GET, HEAD, OPTIONS

{ "terminals": "http://api.datawiz.io/api/v1/terminals/", "products": "http://api.datawiz.io/api/v1/products/", "cashiers": "http://api.datawiz.io/api/v1/cashiers/", "units": "http://api.datawiz.io/api/v1/units/", "shops": "http://api.datawiz.io/api/v1/shops", "loyalty": "http://api.datawiz.io/api/v1/loyalty/", "categories": "http://api.datawiz.io/api/v1/categories/", "receipts": "http://api.datawiz.io/api/v1/receipts/" }

⚠️ **GitHub.com Fallback** ⚠️