- Tabela gromadzi komplet informacji o pojedynczym wywołaniu API: adres, metodę HTTP, nagłówki, treść żądania i odpowiedzi oraz status zwrócony przez usługę.
- Kolumna
KIERUNEKrozdziela dwa scenariusze — PRZYCH to dane przyjęte przez system, WYCH to wywołanie usługi zewnętrznej. - Sześć indeksów zbudowano pod typowe pytania diagnostyczne: co się działo w danym czasie, które wywołania zakończyły się błędem, jak przebiegła konkretna operacja.
- Kolumny typu
varchar(max)rosną szybko, dlatego tabela wymaga zaplanowanej archiwizacji starszych wpisów.
Do czego służy tabela [dbo].[_api_sql]
Integracja przez API zawodzi rzadko, ale gdy już zawiedzie, pytanie brzmi zawsze tak samo: co dokładnie zostało wysłane i co przyszło w odpowiedzi. Tabela [dbo].[_api_sql] odpowiada na nie bez zgadywania, bo przechowuje pełną treść żądania i odpowiedzi razem z nagłówkami oraz kodem statusu HTTP.
Rejestr obejmuje ruch w obie strony. Przy kierunku PRZYCH zapisywane są dane przyjęte do przetworzenia po stronie SQL Server wraz z identyfikatorem operacji, co pozwala powiązać wywołanie z jego skutkiem w bazie. Przy kierunku WYCH tabela dokumentuje wywołanie usługi zewnętrznej — kuriera, systemu ERP albo bramki powiadomień — łącznie z komunikatem błędu, jeśli usługa go zwróciła.
Dla zespołu utrzymania oznacza to jedno miejsce, w którym da się odtworzyć przebieg wymiany danych bez sięgania po logi serwera aplikacji. Dla wdrożeniowca — możliwość sprawdzenia, czy problem leży po stronie systemu, czy kontrahenta.
Komplet danych o jednym wywołaniu mieści się w jednym wierszu, dzięki czemu diagnoza nie wymaga łączenia kilku źródeł logów.
Budowa tabeli — wykaz kolumn
Struktura dzieli się na trzy grupy: metryka wpisu, opis żądania w kolumnach z przedrostkiem REQUEST_ oraz opis odpowiedzi w kolumnach RESPONSE_. Pełny wykaz wygląda następująco:
| Kolumna | Typ | Wymagana | Znaczenie |
|---|---|---|---|
BLAD | varchar(max) tekst bez limitu długości | nie | Błąd wywołania obcej usługi (tylko dla WYCH) |
ID_API_SQL | bigint liczba całkowita 64-bitowa | tak | Identyfikator wiersza tabeli |
KIEDY | datetime data i godzina | tak | Czas utworzenia rekordu |
KIERUNEK | varchar(50) tekst do 50 znaków | tak | Kierunek operacji, PRZYCH - przyjęcie danych, WYCH - wywołanie obcej usługi |
REQUEST_ACTION_DATA | varchar(max) tekst bez limitu długości | nie | Żądanie - dane przekazane do SQL (tylko dla PRZYCH) |
REQUEST_ACTION_UID | varchar(50) tekst do 50 znaków | nie | Żądanie - identyfikator SQL (tylko dla PRZYCH) |
REQUEST_BODY | varchar(max) tekst bez limitu długości | nie | Żądanie - treść |
REQUEST_METODA | varchar(10) tekst do 10 znaków | tak | Żądanie - metoda HTTP |
REQUEST_NAGLOWKI | varchar(max) tekst bez limitu długości | nie | Żądanie - nagłówki |
REQUEST_URL | varchar(4000) tekst do 4000 znaków | nie | Żądanie - adres |
RESPONSE_BODY | varchar(max) tekst bez limitu długości | nie | Odpowiedź z usługi - treść |
RESPONSE_NAGLOWKI | varchar(max) tekst bez limitu długości | nie | Odpowiedź z usługi - nagłówki |
RESPONSE_STATUS | int liczba całkowita | nie | Odpowiedź z usługi - status |
STAMP | timestamp znacznik wersji wiersza | tak | Znacznik czasowy utworzenia rekordu |
Kolumny REQUEST_ACTION_DATA i REQUEST_ACTION_UID wypełniane są wyłącznie dla kierunku PRZYCH, a kolumna BLAD — wyłącznie dla WYCH.
Indeksy i wydajność zapytań
Indeksy odpowiadają pytaniom, które w praktyce zadaje się rejestrowi najczęściej: o przedział czasu, o kierunek ruchu i o wywołania zakończone niepowodzeniem.
| Indeks | Kolumny | Rodzaj |
|---|---|---|
IX__api_sql_KIEDY | KIEDY | zwykły |
IX__api_sql_KIERUNEK | KIERUNEK | zwykły |
IX__api_sql_REQUEST_ACTION_UID | REQUEST_ACTION_UID | zwykły |
IX__api_sql_REQUEST_METODA | REQUEST_METODA | zwykły |
IX__api_sql_RESPONSE_STATUS | RESPONSE_STATUS | zwykły |
PK__api_sql | ID_API_SQL | klucz główny |
Przy dużym ruchu warto rozważyć indeks złożony na parze KIEDY i RESPONSE_STATUS. Zapytanie o błędy z ostatniej doby jest wtedy obsługiwane jednym przeszukaniem zakresu zamiast filtrowania po odczycie.
Ile rejestr zajmuje miejsca i jak długo go przechowywać
Rejestr wywołań rośnie szybciej niż jakakolwiek inna tabela systemowa, bo w jednym wierszu zapisuje pełne treści żądania i odpowiedzi. Przy integracji obsługującej kilka tysięcy wywołań dziennie przyrost liczy się w gigabajtach miesięcznie. Decyzja o okresie przechowywania nie jest więc szczegółem technicznym — przekłada się wprost na czas wykonania kopii zapasowej i koszt przestrzeni dyskowej.
| Wariant | Co zostaje | Zastosowanie |
|---|---|---|
| Pełny zapis | Wszystkie kolumny, wszystkie wywołania | Okres stabilizacji po uruchomieniu integracji, gdy liczy się możliwość odtworzenia każdego przypadku |
| Skrócenie treści | Metryka w całości, treści przycięte do kilku kilobajtów | Praca ustabilizowana — do diagnozy zwykle wystarcza początek odpowiedzi z komunikatem błędu |
| Tylko niepowodzenia | Komplet danych wyłącznie dla statusów 4xx i 5xx | Integracje o dużym wolumenie, w których udane wywołania nie wnoszą informacji |
| Archiwizacja okresowa | Wpisy starsze niż ustalony próg przenoszone do osobnej tabeli | Wymóg zachowania śladu na potrzeby rozliczeń z kontrahentem |
Warianty można łączyć — częstym rozwiązaniem jest pełny zapis niepowodzeń i skrócony zapis wywołań zakończonych powodzeniem.
Osobną kwestią jest ochrona danych. Nagłówki żądań zawierają zwykle token autoryzacyjny, a treść — dane kontrahentów. Rejestr powinien więc podlegać tym samym ograniczeniom dostępu co tabele operacyjne, a nagłówki autoryzacyjne warto maskować już na etapie zapisu.
Jak korzystać z tabeli w praktyce
Rejestr sprawdza się przede wszystkim w trzech sytuacjach — przy diagnozie awarii, przy odbiorze integracji od kontrahenta i przy kontroli obciążenia. W praktyce:
- Zacznij od filtra na
RESPONSE_STATUS >= 400— kody 4xx wskazują na problem po stronie żądania, 5xx po stronie usługi. - Pustej wartości w
RESPONSE_STATUSprzy kierunku WYCH nie ignoruj: zwykle oznacza, że usługa w ogóle nie odpowiedziała, a szczegół znajdziesz w kolumnieBLAD. - Powiąż wpis z operacją w bazie przez
REQUEST_ACTION_UID, jeśli chcesz sprawdzić, jaki dokument powstał w wyniku wywołania. - Zaplanuj cykliczne przenoszenie wpisów starszych niż kilka miesięcy do tabeli archiwalnej — kolumny
varchar(max)zajmują najwięcej miejsca w całej bazie. - Nie zapisuj w rejestrze haseł ani tokenów w postaci jawnej; nagłówki autoryzacyjne warto maskować przed zapisem.
- Do analizy obciążenia grupuj wpisy po godzinie i metodzie HTTP — rozkład zwykle ujawnia wywołania powtarzane niepotrzebnie.
Poniższe zapytanie zestawia nieudane wywołania usług zewnętrznych z ostatniej doby wraz z komunikatem błędu:
SELECT KIEDY,
REQUEST_METODA,
LEFT(REQUEST_URL, 80) AS ADRES,
RESPONSE_STATUS,
LEFT(BLAD, 200) AS KOMUNIKAT
FROM dbo._api_sql
WHERE KIERUNEK = 'WYCH'
AND KIEDY >= DATEADD(DAY, -1, GETDATE())
AND (RESPONSE_STATUS IS NULL OR RESPONSE_STATUS >= 400)
ORDER BY KIEDY DESC;
Funkcja LEFT ogranicza objętość wyniku — pełna treść odpowiedzi bywa liczona w megabajtach i niepotrzebnie obciąża narzędzie, w którym przegląda się wynik.
Rejestr wywołań ma sens tylko wtedy, gdy ktoś do niego zagląda. Warto ustawić proste zapytanie kontrolne uruchamiane raz dziennie i wysyłające podsumowanie liczby błędów — problem z integracją zwykle ujawnia się wtedy, zanim zgłosi go kontrahent.
Powiązane tabele i dokumentacja
Rejestr wywołań API współpracuje z kilkoma innymi strukturami odpowiadającymi za komunikację i śledzenie zdarzeń: