Писали API - порвали XML (два)

Перший API Могоскладу з'явився 10 років тому. Весь цей час ми працюємо над існуючими версіями API та розробляємо нові. А кілька версій API вже встигли поховати.

У цій статті буде багато всього: як створювали API, навіщо він потрібен хмарному сервісу, що дає користувачам, які граблі ми встигли наступити і що хочемо робити далі.

Мене звуть Олег Алексєєв oalexeevя технічний директор і співзасновник МогоСкладу.

Навіщо робити API для сервісу

Наші клієнти, а це десятки тисяч підприємців активно користуються хмарними рішеннями: банкінгом, інтернет-магазинами, товарним обліком, CRM. Підключився до одного – і вже важко зупинитися. І ось уже п'ятий, восьмий, десятий сервіс робить роботу підприємця легшим, але дані між цими хмарними сервісами користувачі переносять вручну. Робота перетворюється на кошмар.

Очевидне рішення – дати користувачам можливість передавати дані між хмарними сервісами. Наприклад, імпортувати та експортувати дані як файли, які потім можна завантажити у потрібний сервіс. Файли зазвичай змінюють формат кожного сервісу. Це більш-менш проста ручна робота, але зі зростанням кількості цих сервісів виконувати її стає все складніше.

Тому наступний крок – API. З ним хмарний сервіс виграє від того, що пов'язує кілька сервісів в одній точці. Поява такої екосистеми залучає нових клієнтів за рахунок додаткових можливостей. Продукт з новим функціоналом стає вигіднішим і кориснішим.

Якщо створювати власні програмні інтерфейси, це приваблює сторонніх продажників у вигляді програмістів, які знають про ваш продукт завдяки API. Вони починають будувати рішення на основі запропонованого API та заробляють гроші на автоматизації завдань своїх замовників.

Облікова система Мого Складу будується на найпростіших процесах. Головне — робота з первинними документами, можливість проводити приймання та відвантаження товару, отримувати на основі первинки звіти для бізнесу. Також є передача даних, наприклад, у хмарну бухгалтерію, та їх отримання з банківських систем або роздрібних точок. Ще ми працюємо з інтернет-магазинами: отримуємо відомості про товари та надсилаємо дані про залишки.

Писали API - порвали XML (два)

Перший API МогоСкладу

За 10 років роботи Мого Складу з API ми обросли всілякими інтеграціями, які дозволяють обмінюватися даними, працювати з банками, проводити оплату та використовувати зовнішню телефонію.

Першого року ми зробили можливість вивантажувати будь-які дані у форматі XML. Тоді користувачам було набагато зрозуміліше і звичніше тримати дані в офлайні, а не в якійсь там хмарі, і ми дали їм це. Вивантаження запускалося ручним експортом з інтерфейсу. Тобто, API це ще не можна було назвати.

Тоді ми стали співпрацювати з компанією Русагро — вони вже використовували «дорослу» ERP для планування виробництва та збуту, а ось завантаження вагонів на заводах автоматизували в Моєму Складі. Так у нас з'явилися перші зачатки справжнього API: обмін між нашим сервісом та ERP відбувався шляхом пересилання великого файлу з даними по всіх типах документів.

Це непоганий варіант для пакетного обміну даними, але разом з документами доводилося передавати їх залежності: відомості про товари, контрагенти та склади. Таке сміттєзвалище не так важко згенерувати при експорті, але досить важко розбирати при імпорті, тому що в одному пакеті приїжджають усі відомості: і про нові документи, і про існуючі.

Перший XML API прожив недовго – через два роки ми почали його перебудову. Ще на старті його роботи ми зробили кілька помилок при побудові програмного інтерфейсу.

Писали API - порвали XML (два)
Як робився XML API: ілюстрація одного з наших архітекторів. До речі, чекайте на його статті.

Ось наші основні помилки:

  1. JAXB-розмітка була зроблена безпосередньо на entity beans. Для спілкування з базою ми використовуємо Hibernate, і на ці ж біни була зроблена JAXB-розмітка. Ця помилка вийшла майже відразу: будь-яке оновлення структури даних призводило до необхідності термінового повідомлення всіх, хто використовує API, або побудови милиць, які б забезпечували сумісність з попередньою структурою даних.
  2. API виростав як доповнення, і спочатку ми не визначили, яку частину продукту він становить. Не думали і про те, чи є API чимось важливим, чи потрібно підтримувати зворотну сумісність перших клієнтів. На якийсь момент кількість користувачів API становила близько 5% від загальної невеликої кількості, і уваги на них не звертали. Зроблена у свій час універсальна фільтрація призвела до того, що нас почали використовувати як бекенд. Фільтрація ця була зовсім не GraphQL, але щось на кшталт того — працювала через безліч параметрів рядка запиту. З таким потужним інструментом користувачам було важко утриматися, і на нас переклали запити так, що вони відправлялися безпосередньо з UI їхніх інтернет-магазинів. Ситуація стала неприємним сюрпризом, тому що надання такої послуги має вимагати іншої тарифікації та взагалі іншого розуміння самого API як продукту.
  3. Через те, що API розвивався не як основний продукт, документація з API проводилася і публікувалася за залишковим принципом через реверс-інжиніринг. Такий шлях здається досить простим та зручним, але суперечить роботі за контрактом. Це коли є якийсь компонент із встановленою схемою роботи. Розробник реалізує його відповідно до цієї схеми та завдання, компонент проходить тестування, клієнт отримує продукт, який відповідає задуму аналітика. Реверс-інжиніринг на ринок викидає продукт, який просто є: з милицями, дивними рішеннями і велосипедами замість потрібного функціоналу.
  4. Весь потік запитів, який надходив через API, можна було проаналізувати не більше як лог Nginx або application server. Це не дозволяло виділити предметні області, хіба що розбити за користувачами та передплатниками. Якщо немає можливості регулювати реєстрацію програми чи клієнтів, аналізувати ситуацію стає неможливо. Ця проблема найменшою мірою вплинула на розвиток API, вона більше про розуміння його затребуваності та наповненості функціоналом.

Спроба номер два: REST API

У 2010 році ми намагалися побудувати систему обміну з онлайн-бухгалтерією БухСофтом. Чи не злетіло. Зате в процесі інтеграції з'явився повноцінний API: REST-сервіс обміну, де були вільні на зразок звернень до операцій у вигляді RPC викликів. Все спілкування з API було наведено до стандартного для ресту режиму: у рядку запиту міститься назва сутності, а операція, яка з нею здійснюється, задається за допомогою http-метода. Ми додали фільтрацію після оновлення сутностей, і у користувачів з'явилася можливість будувати реплікацію зі своїми системами.

У тому ж році з'явився API для розвантаження складських та товарних залишків. Для користувачів стали доступні через API найбільш цінні частини системи — обмін первинними документами та розрахункові дані щодо залишків та собівартості товарів.

У грудні 2015 року RetailCRM опублікував першу сторонню бібліотеку для доступу до нашого API. Її стали досить активно використовувати, при цьому зростала популярність сервісу в цілому, навантаження на API зростало швидше за навантаження на веб-інтерфейс. Одного разу зростання перетворилося на стрибок навантаження.

Писали API - порвали XML (два)

Писали API - порвали XML (два)

І цей стрибок, на який вказує стрілка ліворуч, привів у здивування сервер, що обслуговує наш API. Тиждень ми розбиралися, що саме це навантаження генерує. Виявилося, що це ті самі запити, які транслюються на наш API з фронтів у клієнтів. Усі з'їли близько 50 клієнтів. Ось тут ми й зрозуміли одну зі своїх помилок — повну відсутність лімітів.

У результаті ми запровадили ліміт на кількість одночасних запитів. З одного обліку можна одночасно відкривати не більше двох запитів. Це достатньо для роботи в режимі реплікації для обміну даними в пакетному режимі. А ті, хто хотів використати нас як бекенд, з цього моменту були змушені більше відповідати тарифам, оскільки ввели у свої програмні засоби роботу з кількох обліків.

Упорядковуємо

Вже з 2014 року попит на існуючий API став важливою частиною бізнесу, а сам API генерував найбільший обсяг даних обміну даними з клієнтами. У 2015 році ми запустили проект упорядкування API. Вибрали як формат JSON замість XML і почали будувати його на основі особливостей, які виявили під час реалізації попередньої версії:

  1. Можливість керувати версіями. Версіонування дозволяє розробляти нову версію, не торкаючись існуючої програми та не порушуючи роботу користувачів.
  2. Можливість користувачеві бачити метадані в самій відповіді, яку він отримує.
  3. Можливість обміну величезними документами. Якщо ми обробляємо документ із кількістю позицій більше 4-5 тисяч, це стає проблемою для сервера: довга транзакція, довгий http-запит. Побудували спеціальний механізм, що дозволяє оновлювати документ частинами та керувати окремими позиціями цього документа, надсилаючи їх на сервер.
  4. Інструменти для реплікації були й у попередній версії.
  5. Ліміти за навантаженням — як спадщина граблів, на які настали у попередній версії. Ввели ліміти на кількість запитів у проміжок часу, кількість паралельних запитів та запитів з однієї IP-адреси.

З того моменту ми випустили дві мінорні версії API та запустили кілька спеціалізованих API, але загалом підхід залишився без змін. Оновлений формат обміну та нова архітектура дозволили виправляти недоліки в API набагато швидше.

API МогоСкладу сьогодні

Сьогодні API МогоСкладу вирішує багато завдань:

  • обмін даними з інтернет-магазинами, обліковими системами, банками;
  • одержання розрахункових даних, звітів;
  • використання як бекенд для клієнтських додатків — наші мобільні програми та десктопна каса працюють через API
  • надсилання повідомлень про зміни даних в Моєму складі - webhooks;
  • телефонія;
  • системи лояльності.

На основі API наш гендиректор Аскар Рахімбердієв носоріг за чотири години написав телеграм-бот, який тягає через API залишки: github.com/arahimberdiev/com-lognex-telegram-moysklad-stock

Тепер сухі цифри.

Ось наша статистика зі старого REST API:

  • 400 компаній;
  • 600 користувачів;
  • 2 млн запитів на добу;
  • 200 Гб/добу вихідного трафіку.

А ось до чого ми прийшли по всіх API Мого Складу:

  • більше 70 інтеграцій (частину з них можна подивитися тут www.moysklad.ru/integratsii);
  • 8500 компаній;
  • 12 000 користувачів;
  • 46 млн запитів на добу;
  • 2 Тб/добу вихідного трафіку.

Що далі

Плани розвитку API знаходяться в активному обговоренні. Ми намагаємося враховувати досвід експлуатації, яким нас постачають користувачі. Не завжди і не все виходить робити відразу, але не за горами нова версія API з зручнішими метаданими і менш розлогою структурою, OAuth для автентифікації, API для додатків, що вбудовуються в інтерфейс.

Слідкувати за новинами можна на спеціальному сайті для розробників інтеграцій з Моїм Складом: dev.moysklad.ru.

Джерело: habr.com

Додати коментар або відгук