
Integracja systemów ERP jako źródło przewagi rynkowej. Projektowanie REST API i scenariuszy
Spis treści
Artykuł ma dwie części. Pierwsza część jest adresowana do kadr zarządczych, cały artykuł (obie części) do osób zajmujących się projektowaniem rozwiązań. (22.04.2022 dopisałem Dodatek).
Wstęp
Mamy ogólnoświatową sieć Internet, aplikacje lokalne i w chmurze, aplikacje naszych kontrahentów i aplikacje centralnych urzędów. Wszystkie one współpracują i wymieniają dane, czyli są zintegrowane. Dlatego integracja stała się jednym z obligatoryjnych wymagań każdego systemu informatycznego.
Pogodzenie się z tym, że świat już nigdy nie będzie tak prosty jak 40 lat temu jest nieuniknione. Podobnie jak pogodzenie się z tym, że czasy jednej centralnej aplikacji też odeszły do lamusa. Praktyka zaś pokazuje, że idea zbudowania wszystkich funkcjonalności jako zintegrowanej aplikacji na jednej współdzielonej bazie danych jest utopią.
Dane i ich kontekst czyli informacje
Po pierwsze dane mają różne konteksty, ich znaczenie zależy od kontekstu i miejsca użycia:
Powyżej zobrazowano dane i ich kontekst. Data może być datą urodzin lub datą śmierci i nadal jest to data. Osoba może być obywatelem w państwowym rejestrze, ale może być pracownikiem, klientem itp.. opis osoby (struktura danych) nie zmienia się mimo zmiany jej roli. W rejestrze obywateli data, jako pole (powyżej), nawet taka sama, może tu występować wielokrotnie, jednak ta sama data jako wartość, w rejestrze będącym kalendarzem musi być unikalna.
Powyższe to struktura dokumentu, jak widać znaczenie danych nadaj kontekst ich użycia (dokument, jego sekcja). Takiej struktury, naturalnej z perspektywy biznesowej, nie da się mapować na, pozbawiony redundancji, model relacyjnej bazy danych. Zapisanie tego dokumentu w modelu relacyjnym typowego ERP wymaga stworzenia dodatkowych tablic, a odtworzenie z niej dokumentu wymaga skomplikowanego zapytania SQL do tej bazy (nie w niej dokumentów a jedynie dane): w bazach relacyjnych NIE MA żadnych dokumentów, są wyciągnięte z nich, i pozbawione kontekstu, dane.
Powyższy dokument, bez żadnego problemu: bez utraty kontaktu i bez mnożenia typów dat, zapiszemy w formacie XML w dokumentowej bazie danych .
Wspólna baza danych jest z zasady jednokontekstowa, więc pewnych rzeczy informacji po prostu nie da się tak przetwarzać. To dlatego nie jest możliwe zbudowanie jednego uniwersalnego systemu ERP z centralną relacyjną bazą danych, ale możliwe jest łatwe zintegrowanie kilku specjalizowanych dziedzinowych systemów. Problem ten opisał i wyjaśnił w 2014 roku M.Fowler:

Referencyjny model procesów biznesowych
Czasy monolitów się skończyły i nawet jeżeli planowane jest wdrożenie „jednego ERP”, już nigdy nie będzie to jedyna aplikacja w firmie. Coraz częściej zakres wdrożenia monolitycznego systemu ERP ogranicza się do obszaru nazywanego „back-office” czyli do procesów wspierających. W 1985 roku M.E.Porter (rok 1985 to pierwsze wydanie Strategii Konkurencji ) opisał tak zwany wewnętrzny łańcuch wartości firmy. Graficznie zobrazował go tak:

Powyższy diagram nadal stanowi klasykę procesowego podejścia do zarządzania (patrz Cambridge). Jest to standardowy, bazowy szkielet modelowania procesów biznesowych wewnątrz organizacji (starting point). Procesy biznesowe (czyli także aktywności jako ich wewnętrzna część) zostały tu podzielone na dwie podstawowe grupy: wspierające (suport activities) i operacyjne (primary activities, core).
Pomiędzy grupą procesów wspierających i operacyjnych jest zasadnicza różnica: zmienność i zależność od prawa i standardów. Procesy wspierające są w znacznej mierze regulowane prawem, stanowią standardy zarządzania, normy proceduralne (normy ISO itp.). Ten obszar nie buduje przewagi rynkowej, tu marża powstaje jako wewnętrzna sprawność (obniżanie kosztów). Procesy operacyjne (core) to kluczowy łańcuch budowy marży. To tu powstaje przewaga rynkowa: jakość produktów i usług. To tu są wdrażane standardy branżowe. Tu jest właśnie granica między ERP (procesy wspierające) a aplikacjami dziedzinowymi (WMS, MES, APS, WorkFlow, e‑Commerce i wiele innych).
Głównym powodem tego podziału, i tego że linia podziału jest właśnie tu gdzie jest, jest zmienność. Gdyby porównać między sobą firmy z różnych branż, to okaże się, że obszar procesów wspierających to stabilny obszar administracji, gdzie rotacja kadr jest mała, a ewentualna zmiana miejsca pracy nie zależy od branży i nie wymaga przekwalifikowania. Obszar operacyjny to dedykowane dziedzinowe działania, nacechowane specyfiką konkretnej branży i specjalistami „z dziedziny…”. To dlatego na rynku jest tak wiele dziedzinowych aplikacji, które powstały do zarządzania specyfiką określonych działań, specyficznych dla danej branży. Nie przypadkiem nazywamy te aplikacje „systemami branżowymi”.
W efekcie dzisiejsza sprawna firma (organizacja) będzie miała „standardowy ERP” wdrożony w obszarze procesów wspierających, oraz – poza nim – zestaw dedykowanych, branżowych aplikacji, integrowanych z tym ERP.
Integracja jako wymaganie
Ta część jest adresowana do każdego kto modeluje integracje systemów IT (lub chce się tego nauczyć).
W 2014 artykuł o integracji kończyłem słowami:
Dedykowane dziedzinowe aplikacje coraz częściej są wdrażane etapami zamiast jednego dużego ERP. Taka integracja nie jest wbrew pozorom kosztowna, kosztowny jest brak stosowania dobrych praktyk i wzorców, które warto poznać. Zwinność działania dzisiejszych firm na rynku to wymóg a nie opcja. Zwinność taka to nie jeden duży ERP (monopol jednego usługodawcy), to kilka zintegrowanych, dedykowanych niezależnych aplikacji , wdrażanych bez kastomizacji (wybieramy najlepszy produkt w danym momencie). Ich (aplikacje dziedzinowe) wymiana na inne, przy dobrze wykonanej integracji, to jest proces, który nie generuje monstrualnych kosztów każdorazowej analizy i przeróbki całości IT (kolejnej kastomizacji jednego ERP) w firmie.
(źr.: Wymagania pozafunkcjonalne – integracja – Jarosław Żeliński IT-Consulting)
Modelowanie integracji opisywałem nie raz (patrz wyżej cytowany artykuł): należy udokumentować architekturę (komponenty aplikacyjne i ich powiązania), dokumenty jako agregaty danych, oraz scenariusze opisujące metody osiągania oczekiwanego efektu. Scenariusze dokumentujemy diagramami sekwencji, a zalecane parametry wywołań to agregaty reprezentujące dokumenty (implementowane jako JSON lub XML). Taka postać jest doskonała do testów integralności, jednak bardzo często pojawia się potrzeba przekazania w specyfiakcji wymagań jednego określnego API jako wydzielonej perspektywy, i tu przychodzi z pomocą możliwość stworzenia dedykowanego diagramu klas, którego celem jest udokumentowanie wyłącznie określonego API (np. wymaganego lub ustalnego w toku wdrożenia).
Co to jest REST API?
Przenoszenie Stanów Reprezentacji (ang. Representational state transfer: REST) jest metodą komunikacji, która definiuje zestaw ograniczeń (wymagań) przy tworzeniu usług sieciowych. Usługi sieciowe, które są zgodne z REST, zwane usługami sieciowymi RESTful (RWS), zapewniają interoperacyjność między systemami komputerowymi w Internecie. Usługi RESTful Web Services umożliwiają systemom wzajemny dostęp do danych w formie tekstowej i manipulację nimi, za pomocą jednolitego i predefiniowanego zestawu bezstanowych operacji. Całość nazywamy stylem budowy architektury, jest on w pełni zgodny z obiektowym i komponentowym podejściem do projektowania systemów, a kluczową zasadą jest tu także hermetyzacja i projektowanie zorientowane na odpowiedzialność komponentów. Podstawowe wzorce architektoniczne wykorzystywane przy projektowaniu integracji to Saga, Łańcuch odpowiedzialności i Repozytorium.
Dzięki bezstanowemu protokołowi i standardowych operacji, systemy RESTful uzyskują dużą wydajność, niezawodność i możliwość rozwoju poprzez ponowne wykorzystanie komponentów (hermetyzacja), które mogą być zarządzane i aktualizowane bez wpływu na system jako całość, nawet podczas jego działania.
Ograniczenia architektoniczne czyli wymagania wobec architektury
REST definiuje 6 ograniczeń (to jego główne cechy) architektonicznych, które sprawiają, że każda usługa sieciowa jest prawdziwie RESTful API.
1. Architektura usługobiorca-usługodawca
Zasadą stojącą za ograniczeniami usługobiorca-usługodawca (inne spotykane nazwy: klient usługi i usługodawca, klient-serwer, client – service provider), jest separacja kontekstów. Oddzielenie zadań związanych z interfejsem użytkownika od zadań związanych z przechowywaniem danych poprawia przenośność interfejsów użytkownika na wielu platformach. Poprawia to również skalowalność poprzez uproszczenie komponentów serwera. Być może najbardziej znaczące dla sieci Internet (i dla sieci w ogóle) jest jednak to, że separacja ta (hermetyzacja) pozwala komponentom rozwijać się niezależnie, pozwalając w ten sposób na istnienie w sieci Internet, lub w sieci lokalnej organizacji, wielu różnych i niezależnych domen i zasobów. Hermetyzacja to także niezależność od typów danych: przekazywane dane to wyłącznie ciągi znaków (string), ich typy muszą być uzgodnione po obu stronach (JSON) lub zdefiniowane (XSD/XML).
2. Bezstanowość
Komunikacja usługobiorca-usługodawca jest ograniczona tym, że żaden kontekst usługobiorcy nie jest przechowywany u usługodawcy pomiędzy żądaniami. Każde żądanie od dowolnego usługobiorcy zawiera wszystkie informacje niezbędne do obsłużenia żądania. Stan sesji jest przechowywany zawsze po stronie usługobiorcy (patrz wzorzec projektowy Saga). Stan sesji może być przekazany przez usługodawcę do innej usługi, takiej jak baza danych, aby utrzymać trwały stan przez pewien czas i umożliwić uwierzytelnienie. Usługobiorca zaczyna wysyłać żądania, gdy jest gotowy do przejścia do nowego stanu. Gdy jedno lub więcej żądań jest nierozstrzygniętych, usługobiorca jest uważany za znajdującego się w stanie przejściowym. Reprezentacja każdego stanu aplikacji zawiera odnośniki, które mogą być użyte następnym razem, gdy klient zdecyduje się zainicjować przejście do nowego stanu.
Kluczową cechą tej architektury jest także to, że usługodawca nigdy sam nie wywołuje usługobiorcy!
3. Zdolność buforowania (cache)
Podobnie jak w sieci WWW, usługobiorca i pośrednicy mogą buforować odpowiedzi. Odpowiedzi muszą zatem, w sposób ukryty lub jawny, określać się (być oznaczone) jako buforowalne lub nie, aby zapobiec otrzymywaniu przez usługobiorcę nieaktualnych lub niepoprawnych danych w odpowiedzi na kolejne żądania. Dobrze zarządzane buforowanie częściowo lub całkowicie eliminuje niektóre interakcje usługobiorca-usługodawca, dodatkowo poprawiając skalowalność i wydajność.
4. Warstwy pośrednie
Usługobiorca zazwyczaj nie może stwierdzić, czy jest połączony bezpośrednio z serwerem końcowym, czy z pośrednikiem po drodze. Oznacza to, że usługobiorca nie wie, czy rozmawia z pośrednikiem, czy z właściwym usługodawcą (patrz wzorzec architektoniczny Łańcuch odpowiedzialności). Jeśli więc pomiędzy usługobiorcą a usługodawcą zostanie umieszczone proxy lub load balancer, nie będzie to miało wpływu na komunikację i nie będzie konieczności aktualizowania kodu usługobiorcy lub usługodawcy. Serwery (usługi) pośredniczące mogą poprawić skalowalność systemu poprzez umożliwienie równoważenia obciążenia i zapewnienie współdzielonych pamięci podręcznych. Ponadto, bezpieczeństwo może być dodane jako dodatkowa warstwa pośrednia dla usług sieciowych, by wyraźnie oddzielić logikę biznesową od logiki (reguł) bezpieczeństwa. Dodanie warstwy bezpieczeństwa jako oddzielnej warstwy wymuszają np. wdrażane polityki bezpieczeństwa (patrz wzorzec architektoniczny Repozytorium). Wreszcie, oznacza to również, że usługodawca także może wywoływać wiele innych serwerów w celu wygenerowania odpowiedzi dla usługobiorcy.
5. Kod na żądanie (opcjonalnie)
Serwery usługodawcy mogą tymczasowo rozszerzać lub dostosowywać funkcjonalność usługobiorcy (klienta), przesyłając mu zwrotnie kod wykonywalny: na przykład skompilowane komponenty, takie jak aplety Java, lub skrypty po stronie przeglądarki WWW, takie jak JavaScript (to dotyczy aplikacji internetowych działających w przeglądarce WWW, a nie integracji systemów, przykład w dalszej części).
6. Jednolity interfejs
Jednolity interfejs definiuje komunikację pomiędzy usługobiorcą i usługodawcą. Gdy programista zapozna się z jednym ze zdefiniowanych interfejsów API, powinien być w stanie zastosować podobne podejście do innych interfejsów API, które musi wykonać.
Polecenia HTTP REST
W REST informacje po stronie serwera są traktowane jako zasób, do którego mozna uzyskać dostęp w jednolity sposób za pomocą URI (Uniform Resource Identifiers) i protokołu HTTP (patrz wzorzec architektoniczny Repozytorium). Metody GET, POST, PUT i DELETE są standardowo używane w architekturze integracji opartej na REST. Poniższy schemat zawiera objaśnienie tych metod:

Warto wiedzieć, że zamiast PUT można użyć PATCH, jest to uproszczenie aktualizujące wyłącznie zmienione atrybuty obiektu, więcej tu: REST API – POST vs PUT vs PATCH.
Jak to działa w sieci Internet?
REST pozwala także na obsługę żądania dostępu do zasobów internetowych i manipulowania nimi przy użyciu jednolitego i predefiniowanego zestawu reguł. Interakcja w systemach internetowych opartych na REST odbywa się poprzez internetowy protokół HTTP (Hypertext Transfer Protocol). Na system Restful składają się:
- Żądający zasobów (obsługi) klient (usługobiorca).
- Posiadający te zasoby i udostępniający je serwer.
Np.:

Więcej:
Modelowanie REST API z użyciem UML w Visual Paradigm
Niektóre narzędzia CASE pozwalają na wykonanie dedykowanej dokumentacji API, w sposób pozwalajacy także, w razie takiej potrzeby, na wygenerowanie szkieletu kodu i jego dokumentacji. Z perspektywy modelowania jest to nadal standardowy diagram klas UML, jedynym dodatkiem jest specjalizowany symbol stanowiący abstrakcję interfejsu oferowanego. Z perspktywy UML jest to, znany z Diagramu Struktur Złożonych (Composit Structure Diagram), komponent/klasyfikator z portami WE i WY.

Producent narzędzia CASE Visual Paradigm dostarcza powyższą konstrukcję jako predefiniowaną klasę: dodatkowy stereotyp „zasób REST”, nadając mu dedykowany symbol (profil REST). Tak to opisuje producent na swojej stronie:

Wywołanie API jest podstawowym elementem usługi sieciowej, i powinno być zgodne z REST. Jest to obiekt zawierający URI, metodę żądania http, powiązane parametry oraz specyfikację żądania/odpowiedzi. Każdy z zasobów REST reprezentuje konkretną usługę dostępną na ścieżce określonej przez jego właściwość URI. Dlatego, jeśli chcesz modelować wiele usług, należy narysować wiele zasobów REST. (źr.:: How to design REST API – Visual Paradigm)
Wymienjony „zasób REST” to właśnie opisana abstrakcyjna klasa, zobrazowana jak na rysunku powyżej. Poniżej przykładowy efekt czyli dokumentacja API z użyciem powyższej metody:

Np. Bardzo prosta komunikacja (interfejs oferowany przez ERP, lub interfejs wymagany):

Na powyższym diagramie po lewej mamy prosty klasyfkator pokazujący, że możliwe jest żądanie Faktury lub Zamówienia na podstawie typu i numeru ID dokumentu. Po prawej stronie (uproszczenie) zwrócona, jako wynika żądania, faktura. Jeżeli nasz projekt zawiera detaliczną specyfikację faktury jako agregatu, odpowiedzią byłby ten właśnie agregat, np. agregat w postaci XML znany z dokumentacji JPK lub faktury ustrukturyzowanej (patrz także: Dokument jako wymaganie).
Bardzo ważna uwaga praktyczna: projektowanie integracji, jako wymiany danych, należy realizować w oparciu o kompletne dokumenty (zestawy danych): na API żądamy „Faktury VAT” i po jej otrzymaniu „u siebie” wyciągamy z niej np. „Wartość brutto”. Nie tworzymy (nie żądamy od serwera) API i usługi „Podaj wartość brutto Faktury VAT()” bo to: drastycznie uzależnia od siebie komunikujące się aplikacje, ogromnie podnosi koszty implementacji i testowania, wymaga powtarzania całej tej pracy po każdej zmianie lub aktualizacij serwera, wymaga dedykowanych operacji dla każdej zintegrowanej aplikacji u kontrahenta .
Podsumowanie
Tak więc pogodzenie się z integracją jako wymaganiem jest nieuniknione. Podobnie jak pogodzenie się z tym, że czasy jednej centralnej aplikacji w firmie i centralnej bazy danych, też odeszły do lamusa. Mamy ogólnoświatową sieć Internet, aplikacje lokalne i w chmurze, aplikacje naszych kontrahentów i aplikacje centralnych urzędów. Wszystkie on współpracują, wymieniają dane. To dlatego integracja stała się jednym z obligatoryjnych wymagań każdego systemu informatycznego.
A po co ta dokumentacja? Pełni identyczną rolę jak dobrze zaplanowana trasa podróży: wszystko to co można sprawdzić na mapie przed podróżą pozwoli uniknąć kosztownych niespodzianek w jej trakcie. To znaczy także, że można przekazać to jako wymaganie.
Dodatek czyli co to jest Robot i Saga?
Załóżmy, że mamy sytuację jak poniżej:

Szkic pokazuje hipotetyczne pięć aplikacji i wymianę danych (linie) między nimi oraz z otoczeniem (wszystkie organizacje teraz wymieniają dane z otoczeniem, w tym z Urzędem Skarbowym).
Standardowe aplikacje oferują API jako Interfejs Oferowany (lista usług, które można wywołać), czyli można od nich czegoś żądać. Problem w tym, że ktoś musi to żądanie wysłać. Czy żądanie może wysłać sama z siebie inna aplikacja? Owszem, pod warunkiem że ma taką możliwość (a ma rzadko), lub że dodamy jej (kastomizacja) taką możliwość. Robi się to na poziomie kodu (kastomizacja) lub na poziomie bazy danych (tak zwane trygery). W efekcie powstaje, pokazana poniżej, struktura wzajemnych wywołań, których nic nie koordynuje (każda aplikacja sama, w sobie znanym momencie, inicjuje żądanie wobec innej).

Efekt jaki powstaje to: tak zwany hazard, polegający na tym, że nic nie panuje nad kolejnością tych wywołań. Taki hazard powoduje błędy lub zawieszenia się komunikacji. Próby walki z nim polegają na sztucznym wstawianiu czasu oczekiwania, lub wymuszaniu określonego terminy wywołania. Koszty integracji to koszt tych prac kastomizacyjnych razy liczba aplikacji wymagających tej kastomizacji, całość jest czuła na każdą zmianę takiej sieci bo np. modyfikacja lub wymiana jednej z aplikacji, potencjalnie wymaga reorganizacji całej komunikacji. To tylko część problemów, gdyż bardzo często integracje nadal są realizowane metodą bezpośredniego dostępu do danych jak pokazano poniżej:

Szkodliwość podejścia pokazanego powyżej jest podwójna: pomijamy logikę zarządzania danymi w oprogramowaniu Aplikacja2, kastomizujemy oprogramowanie Aplikacja1. Kastomizacja to duży dodatkowy koszt, ryzyko destabilizacji obu aplikacji (bardzo często się to zdarza) i bardzo często powtarzanie tych prac jest konieczne po każdym upgrade (więcej w artykule Wymagania pozafunkcjonalne – integracja).
Popatrzmy teraz na poniższy szkic:

Korzyści: nie musimy kastomizować aplikacji bo ESB ma wbudowany mechanizm projektowania wywołań API, ESB izoluje od siebie serwery aplikacji: są one hermetyzowane za pomocą adapterów (budujemy je na ESB), więc zmiana konfiguracji aplikacji lub jej wymiana na inną wymaga jedynie ingerencji w jej adapter na ESB. Zastępujemy całkowicie indywidualne integracje z aplikacjami kontrahentów jednym centralnym węzłem integracji (to także forma hermetyzacji lokalnej sieci). W efekcie poszczególne aplikacje nie wymagają żadnych prac kastomizacyjnych, nie dochodzi do opisanych destabilizacji i hazardu, każda wymiana danych jest bezpieczną transakcją kontrolowaną przez ESB zgodnie z wzorcem Saga . Poniżej przykład z użyciem ESB i wzorca Saga:

Wyżej opisane podejście ma także dodatkową ogromną zaletę: dostawcy poszczególnych aplikacji nie muszą ze sobą niczego uzgadniać ani negocjować, co bywa długie i bardzo kosztowne. Mogą być wybierani niezależnie od siebie, w różnym czasie, i nie zakłócają wzajemnie swoimi pracami wdrożeniowymi zachowania innych aplikacji. To efekt separacji aplikacji: żadna nie wymienia danych bezpośrednio z inną.
Czy to niebezpieczne? Co będzie gdy uszkodzi się serwer ESB? Obecnie zabezpieczenie jego dostępności jest znacznie tańsze niż budowanie i utrzymanie wielu łączy integracji „każdy z każdym”. Warto też zwrócić uwagę na to, że może to być (ESB) usługa chmurowa, więc jej wysoka jakość i dostępność będzie często tańsza niż własny zasób.
Jak Budujemy logikę integracji? To opisałem w artykule Wzorce projektowe… integracje realizujemy na bazie wzorca SAGA , czyli budujemy skrypty realizujące wywołania (pobranie i wysłanie danych) w ustalonej kolejności i w ustalonym czasie.
A Roboty? Słynne i modne ostatnio Roboty to właśnie te skrypty realizujące scenariusze integracji na szynie ESB, znane od kilku dekad .
Źródła
Inne artykuły na podobny temat
- Wymagania pozafunkcjonalne – integracja
- Opis Przedmiotu Zamówienia – instrukcja nie tylko dla prawników
- CHMURY – od rozbudowanych rozwiązań autonomicznych do struktur złożonych z różnego rodzaju rozproszonych usług
- RE: Duży monolityczny ERP czy integracja
- Kastomizacja oprogramowania standardowego, aspekty ekonomiczne: Recenzja i rekomendacje

Od 1991 roku realizuje projekty z zakresu analiz i projektowania systemów, dla urzędów, firm i organizacji. Od 1998 roku prowadzi samodzielne studia i prace badawcze z obszaru analiz systemowych i modelowania (ORCID). Od 2005 roku nieetatowy wykładowca akademicki, obecnie Wyższa Szkoła Informatyki Stosowanej i Zarządzania pod auspicjami Polskiej Akademii Nauk w Warszawie. Czytaj więcej o autorze. Sprawdź dostępne Szkolenia i Warsztaty.
Na pewnym forum w mediach społecznościowych, padło pytanie o „robotyzację procesów” i o to co to za nowa technologia. Musiałem nieco rozczarować pytającego, bo odpisałem: nie jest to nic nowego poza nową nazwą. To co teraz modnie nazywamy robotami, to niewielki program (microservice) realizujący określony scenariusz zbudowany na bazie wzorca saga, integrujący aplikacje z użyciem REST API.
Interesujący opis projektowania REST API także tu: https://swagger.io/resources/articles/best-practices-in-api-design/