Integrowanie aplikacji webowych - wybór mechanizmu

Integrowanie aplikacji webowych polega na tym, że jeden system przekazuje drugiemu dane albo zdarzenie bez udziału człowieka, który przepisywałby je ręcznie. Sposób przekazania wyznacza zachowanie całości w razie awarii: przy wywołaniu bezpośrednim błąd odbiorcy natychmiast zatrzymuje nadawcę, a przy kolejce nadawca pracuje dalej, a wiadomości czekają. Wybór mechanizmu jest więc decyzją o odporności, a nie tylko o technologii.

Wymianę można opisać przez kierunek i moment. Przy modelu pobierania (pull) odbiorca pyta nadawcę, kiedy potrzebuje danych. Przy modelu wypychania (push) nadawca informuje odbiorcę, gdy coś się zdarzyło. Do tego dochodzi warstwa pośrednicząca, czyli oprogramowanie typu middleware, które tłumaczy formaty oraz pilnuje uwierzytelniania i szyfrowania transmisji.

MechanizmKierunekKiedy pasujeGłówne ryzyko
API RESTpobieranie lub zlecenie operacjiodczyt bieżących danych, zapis pojedynczego dokumentuniedostępność odbiorcy blokuje wywołującego
Webhookwypychanie zdarzeńpowiadomienie o zmianie statusu bez odpytywaniautrata powiadomienia, gdy odbiorca nie odpowiada
Kolejka komunikatówwypychanie z buforemduże wolumeny, niestała dostępność odbiorcyduplikaty i zmiana kolejności komunikatów
Logowanie SSOwspólna tożsamośćjeden login do kilku aplikacjiwygasanie i unieważnianie tokenów

Reguła: integracja przenosi kontrakt danych, a nie tylko dane - zmiana pola w jednym systemie bez uzgodnienia zatrzymuje drugi.

Pełny przykład wyboru kanału między magazynem a systemem księgowym opisuje artykuł Integracja WMS z ERP - REST i kolejki. Ogólne zasady łączenia programów, niezależnie od branży, przedstawia tekst o integracji systemów informatycznych.

API REST jako kontrakt między aplikacjami

REST (Representational State Transfer) jest stylem architektury, w którym system udostępnia zasoby pod adresami URL, a klient operuje na nich metodami HTTP. Zasobem bywa zamówienie albo awizacja. Adres identyfikuje zasób, metoda wskazuje czynność, a kod odpowiedzi mówi o wyniku. Zbiór takich adresów i formatów danych stanowi kontrakt, który obie strony muszą respektować. Praktyczne zasady projektowania interfejsów zawiera przewodnik projektowania interfejsów API w Azure Architecture Center.

WywołanieZnaczenieTypowy kod odpowiedzi
GET /api/v1/zamowienia?od=2026-09-01lista zamówień od daty200
POST /api/v1/zamowieniautworzenie zamówienia201 z adresem nowego zasobu
PUT /api/v1/zamowienia/1024zastąpienie zamówienia nową treścią200 lub 204
DELETE /api/v1/zamowienia/1024anulowanie zamówienia204

Tworzenie dokumentu przez POST niesie ryzyko duplikatu: jeśli klient nie dostanie odpowiedzi z powodu przerwanego połączenia, ponowi wywołanie i system utworzy drugi dokument. Rozwiązaniem jest klucz idempotencji, czyli unikalny identyfikator operacji przesyłany w nagłówku. Odbiorca zapamiętuje klucze i przy powtórzeniu zwraca wynik pierwszego wykonania. Poniższy przykład jest poglądowy.

using var req = new HttpRequestMessage(HttpMethod.Post, "https://erp.przyklad.pl/api/v1/zamowienia");
req.Headers.Add("Idempotency-Key", zamowienie.NumerZewnetrzny);
req.Content = JsonContent.Create(zamowienie);

using var odp = await http.SendAsync(req, ct);
if (odp.StatusCode == HttpStatusCode.Conflict)
{
    // zamówienie o tym kluczu już przyjęto, nie tworzymy drugiego
    return;
}
odp.EnsureSuccessStatusCode();
Wiele okien z komunikatami i panelami danych ilustrujące wymianę komunikatów między systemami
Strumień komunikatów między systemami - każdy wymaga potwierdzenia przyjęcia i zabezpieczenia przed powtórzeniem.

Wersjonowanie i zmiany kontraktu

Kontrakt zmienia się razem z systemami, więc numer wersji w adresie (v1, v2) pozwala prowadzić dwie wersje równolegle. Dodanie nowego, opcjonalnego pola nie psuje istniejących klientów, natomiast usunięcie pola, zmiana jego typu lub znaczenia wymaga nowej wersji. Stara wersja pozostaje dostępna przez uzgodniony okres, a odbiorcy dostają informację o terminie jej wyłączenia. Przykład interfejsu udostępnianego przewoźnikom, którego zmiany trzeba uzgadniać, opisuje artykuł o awizacji transportu przez portal i API.

Paginacja i limity żądań

Endpoint zwracający listę nie powinien oddawać wszystkich rekordów naraz. Parametry limitu i przesunięcia albo kursora dzielą wynik na strony, a odpowiedź wskazuje adres następnej. Limit liczby wywołań na minutę chroni serwer przed pętlą w cudzym systemie: po przekroczeniu zwraca kod 429 i nagłówek z czasem, po którym można ponowić żądanie. Klient integracji obsługuje ten kod jak zwykłą sytuację, a nie awarię.

Mapowanie danych i formaty

Ten sam dokument bywa opisany inaczej w każdym systemie. Jeden zapisuje kraj jako kod dwuliterowy, drugi jako pełną nazwę, jeden podaje datę w strefie lokalnej, a drugi w UTC. Mapowanie polega na ustaleniu, które pole odpowiada któremu, oraz jak tłumaczy się wartości słownikowe. Najczęściej używanym formatem wymiany jest JSON, choć starsze systemy nadal korzystają z XML i usług SOAP. Daty warto przesyłać w formacie ISO 8601 z jawnym przesunięciem strefowym, a kwoty jako liczby dziesiętne z osobnym polem waluty, a nie jako liczby zmiennoprzecinkowe, które zaokrąglają wartości.

Tabela mapowania, prowadzona jako dokument współdzielony przez obie strony, jest pierwszym miejscem, do którego zagląda się przy niezgodności danych. Gdy jej brakuje, wiedza o tym, co znaczy pole „status” w każdym systemie, istnieje tylko w głowach wdrożeniowców.

Webhooki - powiadomienia w drugą stronę

Odpytywanie systemu co minutę o zmianę statusu obciąża obie strony i daje opóźnienie do jednego cyklu. Webhook odwraca kierunek: odbiorca udostępnia adres, a nadawca wysyła na niego żądanie POST w chwili zdarzenia. Odbiorca musi jednak sprawdzić, że wiadomość pochodzi od zaufanego nadawcy. Najczęściej służy do tego podpis HMAC: nadawca oblicza skrót treści z użyciem wspólnego sekretu i wysyła go w nagłówku, a odbiorca liczy własny i porównuje. Algorytm opisuje dokument RFC 2104.

static bool PodpisPoprawny(string tresc, string podpisHex, byte[] sekret)
{
    using var hmac = new HMACSHA256(sekret);
    var obliczony = hmac.ComputeHash(Encoding.UTF8.GetBytes(tresc));
    var przeslany = Convert.FromHexString(podpisHex);
    // porównanie w stałym czasie, żeby nie zdradzać długości zgodnego prefiksu
    return CryptographicOperations.FixedTimeEquals(obliczony, przeslany);
}

Odbiorca powinien odpowiedzieć kodem 2xx możliwie szybko, a właściwe przetwarzanie przenieść do tła. Nadawca, który nie otrzyma potwierdzenia w wyznaczonym czasie, ponowi wysyłkę, często z rosnącymi odstępami. Ta sama wiadomość może więc dotrzeć więcej niż raz, dlatego odbiorca zapisuje identyfikator zdarzenia i pomija powtórzenia. Bez takiego zabezpieczenia jedno anulowanie zamówienia mogłoby zostać wykonane dwukrotnie.

Reguła: webhook jest powiadomieniem, a nie gwarancją dostarczenia - odbiorca musi mieć sposób nadrobienia zaległości przez zapytanie do API.

Kolejki komunikatów i odporność na błędy

Kolejka rozdziela nadawcę i odbiorcę w czasie. Nadawca zapisuje komunikat i idzie dalej, a odbiorca pobiera go, gdy ma zasoby. Wzorzec ten wygładza piki obciążenia: godzina, w której partner wysyła tysiąc dokumentów, nie przeciąża systemu, bo komunikaty czekają w kolejce na przetworzenie w stałym tempie. Wzorzec opisuje strona o wyrównywaniu obciążenia przez kolejkę.

CechaWywołanie synchroniczneKolejka komunikatów
Odpowiedź dla nadawcywynik operacji od razutylko potwierdzenie przyjęcia komunikatu
Awaria odbiorcybłąd po stronie nadawcykomunikaty czekają na wznowienie
Kolejnośćzgodna z kolejnością wywołańzależna od konfiguracji, często nie gwarantowana
Duplikatyryzyko przy ponowieniu wywołaniaryzyko przy ponowieniu dostarczenia

Powtórzenia i idempotentny odbiorca

Większość kolejek gwarantuje dostarczenie co najmniej raz, co oznacza, że ten sam komunikat może przyjść dwukrotnie. Odbiorca zapisuje więc identyfikator komunikatu w tej samej transakcji, w której zapisuje efekt biznesowy. Klucz główny na kolumnie identyfikatora odrzuca powtórzenie, a błąd naruszenia klucza jest sygnałem, że komunikat już przetworzono.

-- przykład poglądowy, nazwy nie odwzorowują schematu żadnego produktu
CREATE TABLE dbo.PrzetworzoneKomunikaty (
    MessageId       uniqueidentifier NOT NULL PRIMARY KEY,
    PrzetworzonoUtc datetime2(0)     NOT NULL DEFAULT SYSUTCDATETIME()
);

BEGIN TRANSACTION;
    INSERT INTO dbo.PrzetworzoneKomunikaty (MessageId) VALUES (@MessageId);
    UPDATE dbo.Zamowienie SET Status = @Status WHERE ZamowienieId = @Id;
COMMIT;

Komunikaty, których nie da się przetworzyć mimo kilku prób, przenosi się do osobnej kolejki błędów (dead-letter queue). Dzięki temu jeden uszkodzony komunikat nie blokuje reszty, a operator może obejrzeć komunikat, a po poprawieniu danych wysłać go ponownie. Strategię ponawiania z rosnącymi odstępami opisuje wzorzec ponawiania operacji.

Schemat integracji ERP z sześciokątnymi modułami połączonymi liniami przepływu danych
Schemat połączeń wokół systemu ERP - kontrakt danych określa, które moduły wymieniają jakie dokumenty.

Wzorzec skrzynki nadawczej

Nadawca stoi przed pytaniem, jak zapisać dokument w bazie i wysłać komunikat tak, aby nie zdarzyło się jedno bez drugiego. Wzorzec skrzynki nadawczej (outbox) zapisuje komunikat w tabeli w tej samej transakcji co dokument, a osobny proces odczytuje tabelę i wysyła zawartość do kolejki. Rozwiązanie to opisuje artykuł Integracja WMS z ERP - REST i kolejki, w którym pokazano je na przykładzie wymiany potwierdzeń przyjęć i wydań. Podobne mechanizmy ma system TMS online przy przyjmowaniu zleceń z ERP.

SSO i wspólna tożsamość między aplikacjami

Gdy pracownik korzysta z kilku aplikacji, osobne hasła do każdej z nich mnożą konta i ryzyko. Logowanie jednokrotne (SSO) przenosi uwierzytelnianie do jednego dostawcy tożsamości, a aplikacje ufają jego poświadczeniom. W nowych systemach webowych używa się w tym celu protokołu OpenID Connect, który dodaje warstwę tożsamości do standardu autoryzacji OAuth 2.0. Podstawy opisuje dokumentacja OpenID Connect w Microsoft Entra, a sam mechanizm autoryzacji definiuje RFC 6749.

ElementRola w logowaniu
Dostawca tożsamościuwierzytelnia użytkownika i wydaje tokeny
Aplikacja (klient)przekierowuje użytkownika do dostawcy i przyjmuje tokeny
Token tożsamościpotwierdza, kim jest użytkownik, i zawiera jego atrybuty
Token dostępupozwala wywołać API w zakresie określonych uprawnień

Przebieg zwykłego logowania z kodem autoryzacyjnym jest następujący: aplikacja przekierowuje przeglądarkę do dostawcy, użytkownik loguje się tam, a dostawca odsyła przeglądarkę z jednorazowym kodem. Aplikacja wymienia kod na tokeny w bezpośrednim połączeniu z dostawcą, więc tokeny nie przechodzą przez pasek adresu. Dla aplikacji przeglądarkowych dodaje się mechanizm PKCE, który wiąże wymianę kodu z konkretnym żądaniem.

Po zalogowaniu aplikacja musi jeszcze ustalić, co użytkownik może zrobić. Token tożsamości zawiera atrybuty, w tym przynależność do grup, a aplikacja mapuje je na własne role. Zmiana grupy w katalogu zmienia więc uprawnienia po następnym logowaniu lub odświeżeniu tokenu. Odebranie konta w katalogu nie kończy natychmiast sesji już wystawionych, dlatego czas życia tokenów i sesji dobiera się do ryzyka: im krótszy, tym szybciej zmiana dociera do aplikacji.

Token dostępu jest krótkotrwały, a jego ważność ogranicza skutki kradzieży. Do jego odświeżania służy osobny token, który przechowuje się ostrożniej. W firmowych sieciach dostawcą bywa Active Directory z federacją, a wtedy pracownik zalogowany na stacji nie wpisuje hasła ponownie. Przykład takiego układu w systemie magazynowym przedstawia artykuł o logowaniu i autoryzacji w programie WMS, a zasady sesji po stronie aplikacji omawia tekst Aplikacja webowa - architektura i sesje.

Integracje w przeglądarce - CORS i klucze API

Skrypt działający na stronie jednej domeny nie może domyślnie czytać odpowiedzi z innej domeny. Zasadę tę, zwaną polityką tego samego pochodzenia, przeglądarka egzekwuje sama. Aby aplikacja mogła legalnie wywołać cudze API z poziomu JavaScriptu, serwer odbiorcy musi wysłać nagłówki CORS, które wymieniają dozwolone pochodzenia oraz metody. Mechanizm opisuje dokumentacja CORS w MDN.

builder.Services.AddCors(o => o.AddPolicy("Partner", p => p
    .WithOrigins("https://portal.przyklad.pl")
    .WithMethods("GET", "POST")
    .WithHeaders("Content-Type", "Authorization")));

app.UseCors("Partner");

Reguła CORS chroni użytkownika przeglądarki, ale nie zastępuje uwierzytelniania: program spoza przeglądarki ignoruje nagłówki i wywoła adres bezpośrednio. Dlatego każde wywołanie musi nieść poświadczenia sprawdzane na serwerze. Klucz API identyfikuje aplikację, lecz nie użytkownika, i zwykle sprawdza się w integracjach między serwerami. Gdy trzeba wiedzieć, kto wykonuje operację, stosuje się token użytkownika z SSO. Klucze i sekrety przechowuje się w konfiguracji środowiska, nigdy w kodzie przeglądarkowym.

Monitorowanie i obsługa błędów integracji

Integracja, która działa po cichu, zawodzi po cichu. Brak dokumentu w systemie odbiorczym wychodzi na jaw dopiero, gdy ktoś go potrzebuje, więc trzeba mierzyć samą wymianę. Przydatne wskaźniki to liczba komunikatów w kolejce, wiek najstarszego z nich, odsetek odpowiedzi błędnych oraz liczba pozycji w kolejce błędów. Wzrost wieku najstarszego komunikatu wykrywa awarię odbiorcy wcześniej niż skargi użytkowników.

WskaźnikCo sygnalizujePierwsza czynność
Wiek najstarszego komunikatuodbiorca nie nadąża lub nie działasprawdzić stan usługi odbiorczej
Odsetek odpowiedzi 4xxniezgodność kontraktu lub błędne daneporównać treść żądania ze specyfikacją
Odsetek odpowiedzi 5xxawaria po stronie partnerawłączyć ponawianie i powiadomić partnera
Liczba pozycji w kolejce błędówkomunikaty wymagające decyzji człowiekaobejrzeć komunikat i poprawić dane

Każda wymiana dostaje identyfikator korelacji, który przechodzi przez wszystkie systemy i trafia do dzienników. Po nim analityk odnajduje losy jednego dokumentu od wystawienia do potwierdzenia. Zasady nadzoru nad aplikacją po wdrożeniu opisuje artykuł o utrzymaniu dedykowanych aplikacji webowych, a przykład interfejsu reklamacji, z którego korzystają inne systemy, przedstawia tekst RMA system - architektura i integracje.

Testy kontraktu w potoku wdrożeniowym sprawdzają, czy zmiana kodu nie zmieniła formatu wysyłanych danych, co opisuje artykuł o procesie wytwórczym aplikacji webowych. Usługi integracji z systemami klasy ERP producent przedstawia na stronie integracja ERP w ofercie SoftwareStudio.