Писани 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 се развиваше не като основен продукт, документацията му се произвеждаше и публикуваше на остатъчен принцип — чрез реверс инженеринг. Този път изглежда достатъчно прост и удобен, но противоречи на работата по договор. Това е, когато има определен компонент с предварително зададена схема на работа. Разработчикът го реализира в съответствие с тази схема и задачата, компонентът преминава тестиране, клиентът получава продукт, който отговаря на замисъла на аналитика. Реверс инженерингът обаче на пазара предлага продукт, който просто съществува: с импровизации, странни решения и велосипеди вместо необходимия функционал.
  4. Целият поток от запитвания, които пристигаха чрез API, можеше да бъде анализиран само по лог Nginx или application server. Това не позволяваше да се разпределят предметните области, освен ако не се раздели по потребители и абонати. Ако няма възможност да се регулира регистрацията на приложения или клиенти, анализирането на ситуацията става невъзможно. Тази проблема в най-малка степен повлия на развитието на API, тя е повече свързана с разбирането на неговата търсеност и напълнението с функционал.

Опит номер две: REST API

През 2010 година се опитахме да създадем система за обмен с онлайн счетоводство — БухСофтом. Не успяхме. В процеса на интеграцията обаче се появи пълноценен API: REST-сервис за обмен, където липсваха свободи като извиквания на операции в вид на RPC. Цялата комуникация с API беше приведена към стандартния за REST режим: в строката на заявката е включен името на сущността, а операцията, която се извършва с нея, се задава с помощта на http-метод. Добавихме филтриране по времето за обновление на сущностите, и на потребителите им стана възможно да изграждат репликация със своите системи.

В същата година се появи API за извеждане на складови и товарни остатъци. Чрез API на потребителите станаха достъпни най-ценните части от системата — обмен на първични документи и счетоводни данни за остатъците и себестойността на стоките.

През декември 2015 година RetailCRM публикува първата странична библиотека за достъп до нашия API. Тя стана доста активно използвана, като същевременно популярността на услугата нарастваше, а натоварването на API нарастваше по-бързо от натоварването на уеб интерфейса. Един ден ръстът прерасна в скок на натоварването.

Писани API — разкъсани XML (две)

Писани API — разкъсани XML (две)

И този скок, на който показва стрелката вляво, доведе до пълно изумление на сървъра, обслужващ нашия API. Цяла седмица разглеждахме как точно тази натоварване се генерира. Оказа се, че това са онези заявки, които се трансферират към нашия API от клиентските фронтове. Всичко дойде от около 50 клиенти. Тук разбрахме една от нашите грешки — пълно отсъствие на лимити.

В резултат ние въведохме лимит на броя на simultанни заявки. От една и съща сметка ставаше възможно едновременно да се откриват не повече от две заявки. Това е достатъчно за работа в режим на репликация за обмен на данни в пакетен режим. А тези, които искаха да ни използват като бекенд, от този момент бяха принудени да отговарят повече на тарифите, тъй като внедриха работа с няколко учетни записи в своите софтуерни средства.

Подреждаме

Вече от 2014 година търсенето на съществуващия API стана важна част от бизнеса, а самият API генерираше най-голямото количество данни в обмена с клиентите. През 2015 година стартирахме проект за подреждане на API. Избрахме формат JSON вместо XML и започнахме да го изграждаме на основата на особеностите, които установихме при реализирането на предишната версия:

  1. Възможност за управление на версиите. Версионирането позволява разработването на нова версия, без да се засяга съществуващото приложение и без да се нарушава работата на потребителите.
  2. Възможност за потребителя да види метаданните в самия отговор, който получава.
  3. Възможност за обмен на големи документи. Ако обработваме документ с количество позиции, надвишаващо 4-5 хиляди, това става проблем за сървъра: дълга транзакция, дълъг http-заявка. Създадохме специален механизъм, позволяващ обновяване на документа на части и управление на отделни позиции от този документ, изпращайки ги на сървъра.
  4. Инструменти за репликация — имаше и в предишната версия.
  5. Лимити по натоварването — наследство от грабли, в които стъпихме в предишната версия. Въведохме лимити за брой заявки за определен период, брой паралелни заявки и заявки от един ip-адрес.

Оттогава пуснахме две минорни версии на API и стартирахме няколко специализирани API, но общият подход остана без промяна. Обновеният формат на обмена и новата архитектура позволиха да се поправят недостатъците в API много по-бързо.

API на МоегоСклада днес

Днес API на МоегоСклада решава много задачи:

  • обмен на данни с онлайн магазини, счетоводни системи, банки;
  • получаване на изчислителни данни, отчети;
  • използване като бекенд за клиентски приложения — нашите мобилни приложения и десктопната каса работят чрез API.
  • изпращане на уведомления за промени в данните в МоегоСклада — webhooks;
  • телефония;
  • системи за лоялност.

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

Сега сухи цифри.

Ето нашата статистика за стария REST API:

  • 400 компании;
  • 600 потребители;
  • 2 млн заявки на ден;
  • 200 Гб/ден изходящ трафик.

А ето до какво стигнахме по всички API на МоегоСклада:

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

Какво следва

Плановете за развитие на API са в активна дискусия. Стремим се да вземем предвид опита от експлоатацията, който ни осигуряват потребителите. Не винаги и не всичко успяваме да направим веднага, но новата версия на API с по-удобни метаданни и по-малко сложна структура, OAuth за удостоверяване и API за вграждане в интерфейса на приложенията е близо.

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

Източник: habr.com

Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри 🔥 Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри | ProHoster