Ten artykuł rozszerza dwa porównania opublikowane już na tym blogu: naszą recenzję kompatybilności PostgREST i jej alternatyw oraz nasze porównanie poświęcone warstwom GraphQL w Postgres. Tutaj zmienia się kąt: siatka decyzyjna pomiędzy trzema sposobami budowania warstwy API, z Hasurą traktowaną ze względu na uprawnienia i punkty rozszerzenia biznesowego, a nie składnię GraphQL, oraz ręcznie napisany interfejs API jako opcję samą w sobie, a nie prostą linię „else” na dole tabeli.
Najważniejsze
- PostgREST automatycznie generuje interfejs API REST ze schematu Postgres — nie jest możliwa dowolna logika biznesowa, jedyną granicą bezpieczeństwa pozostaje RLS.
- Hasura dodaje własny system uprawnień według roli i tabeli, akcje umożliwiające podłączenie biznesowego webhooka, wyzwalacze zdarzeń i punkty końcowe RESTified na swoim silniku GraphQL.
- Niestandardowe API (Node.js, Express, Fastify...) daje całkowitą kontrolę nad logiką biznesową, walidacją i uwierzytelnianiem — kosztem samodzielnego pisania, testowania i utrzymywania wszystkiego.
- W Aurabase warstwa PostgREST jest prawdziwą instancją; logika biznesowa wykraczająca poza CRUD przechodzi przez funkcje SQL udostępniane w RPC lub przez funkcje brzegowe, a nie przez oddzielny serwer węzła do hostowania.
- Te trzy podejścia niekoniecznie wykluczają się wzajemnie: łączenie PostgREST dla CRUD i niestandardowego interfejsu API dla wrażliwych operacji jest powszechnym wzorcem w produkcji.
Prawdziwy wybór: kto i gdzie pisze logikę biznesową
Pod pytaniem „PostgREST lub Hasura lub niestandardowe API” kryje się bardziej przydatne pytanie: kto pisze logikę biznesową, za pomocą jakiego narzędzia i kto używa tego kodu w produkcji? Te trzy architektury reagują inaczej i ta różnica kształtuje wszystko inne – bezpieczeństwo, szybkość wdrożenia, dług techniczny w dłuższej perspektywie.
| Pochodzenie API | Wygenerowano na podstawie schematu SQL | Wygenerowano ze schematu, poprzez silnik GraphQL Hasura | Napisane trasa po trasie, ręcznie |
|---|---|---|---|
| Niestandardowa logika biznesowa | Tylko funkcje SQL (RPC). | Akcje (webhook) + wyzwalacze zdarzeń | Dowolny kod, bez ograniczeń narzędziowych |
| Model bezpieczeństwa | RLS Postgres, rola kierowana przez JWT | Uprawnienia specyficzne dla roli/tabeli, a nie delegacja do RLS | Co kodujesz (oprogramowanie pośrednie, ORM, opcjonalny RLS) |
| Aby pomieścić dodatkowo | Nic — lekki plik binarny | Silnik Hasura z własną bazą metadanych | Kompletny serwer aplikacji |
| Krzywa uczenia się | Niski, jeśli zespół już wie, jak pisać SQL | Medium — nowy system uprawnień i konfiguracji | Nic na narzędziu, ale wszystko inne do zaprojektowania |
| POSTGREST | HASURA | NIESTANDARDOWE API |
Żadna z trzech kolumn nie jest ściśle lepsza: każda przenosi pracę gdzie indziej. PostgREST przenosi go do SQL, Hasura do konfiguracji i webhooków, niestandardowego API do klasycznego kodu aplikacji.
PostgREST: API jako bezpośrednie odzwierciedlenie schematu
PostgREST przekształca Twój schemat Postgres w interfejs API REST — filtry, osadzanie relacji, RPC, RLS sterowane przez JWT — bez konieczności pisania zaplecza. Szczegółowo opisujemy ten zakres w naszym artykule na temat jego rzeczywistej kompatybilności z i jego alternatyw; dla tego porównania liczy się to, gdzie zatrzymuje się PostgREST.
PostgREST nie ma pojęcia o dowolnej logice biznesowej. Każda reguła musi być wyrażona w języku SQL: funkcja RPC, wyzwalacz, ograniczenie, polityka RLS. Jest to akceptowane ograniczenie, a nie przeoczenie — diagram pozostaje jedynym źródłem prawdy, co eliminuje wszelkie odchylenia między warstwą aplikacji a bazą, której służy.
Konkretnie nie da się zadzwonić do zewnętrznej usługi płatniczej, wysłać e-maila z potwierdzeniem ani obliczyć wyniku w JavaScript na podstawie bezpośredniego żądania PostgREST. Ta logika musi albo znajdować się w SQL (funkcja pl/pgsql), albo zostać wywołana na zewnątrz - wyzwalacz, który publikuje zdarzenie NOTIFY, odsłuchiwane przez zewnętrzną usługę, która nie jest już PostgREST.
Hasura: zadeklarowane uprawnienia, logika biznesowa przeszczepiona przez webhook
Nasz artykuł na temat warstw GraphQL w Postgresie szczegółowo opisuje, gdzie działa silnik Hasura i czym różnią się jego uprawnienia od RLS Postgres. Tutaj mamy do czynienia z logiką biznesową: jak i gdzie podłączyć niestandardowy kod do bazy danych zarządzanej przez Hasurę.
Akcja Hasura udostępnia niestandardową mutację lub zapytanie GraphQL, wspierane przez webhook HTTP napisany w wybranym przez Ciebie języku. Hasura sprawdza poprawność danych wejściowych zgodnie z zadeklarowanym schematem, wywołuje webhook, a następnie zwraca odpowiedź klientowi. Jest to brama do dowolnej logiki wykraczającej poza CRUD: połączenie z dostawcą płatności, złożone obliczenia, wieloetapowa orkiestracja.
Wyzwalacze zdarzeń podążają w odwrotnym kierunku: wstawienie, aktualizacja lub usunięcie w tabeli wyzwala element webhook, asynchronicznie i z automatycznym ponownym uruchomieniem w przypadku awarii. Jest to mechanizm używany przez większość integracji Hasury do synchronizacji usług strony trzeciej (rozliczenia, poczta transakcyjna, wyszukiwarka) bez łączenia tego kodu z początkowym żądaniem klienta.
Hasura może również udostępnić już napisane zapytanie GraphQL jako typową trasę REST, z nazwaną ścieżką i parametrami — jego punktami końcowymi RESTified, zgodnie z terminologią własnej dokumentacji. Przydatne, jeśli Twój zespół frontendowy woli korzystać z REST, nie rezygnując z podstawowego silnika uprawnień GraphQL.
Uprawnienia Hasury to system specyficzny dla Hasury, na rolę i na tabelę, a nie delegacja do Postgres RLS. Dwa miejsca do audytowania reguł dostępu zamiast jednego — rzeczywisty koszt w porównaniu z elastycznością uzyskaną dzięki działaniom i wyzwalaczom zdarzeń.
Przypomnienie kontekstowe, opracowane w naszym dedykowanym artykule: Hasura ponownie skupiła swoją komunikację na PromptQL, warstwie przeznaczonej dla agentów AI, od czerwca 2025 r. – bez usuwania silnika GraphQL, który nadal jest przedstawiany jako „przetestowany w boju” na swojej oficjalnej stronie internetowej.
Niestandardowe API (Node.js, Express, Fastify): koduj wszystko, kontroluj wszystko
Odręcznie napisane API z definicji nie ma żadnych ograniczeń: dowolna logika biznesowa, w dowolnym języku, z dowolnymi zależnościami. Jest to także jedyna z trzech opcji, w przypadku której nic nie jest generowane — każda trasa, każda weryfikacja, każde połączenie z bazą danych to kod, którego jesteś właścicielem i który musisz utrzymywać.
Co ten model oferuje w zamian za pracę ręczną: pełną kontrolę nad błędami i zwracanymi kodami HTTP, klasyczną testowalność (procedury obsługi, a nie konfiguracja deklaratywna) i brak konieczności nauki nowego DSL dla zespołu, który już opanował jego język.
Ile to kosztuje, w zamian: CRUD, paginacja i filtry do ręcznego pisania i utrzymywania dla każdego zasobu; uwierzytelnianie i autoryzacja do samodzielnego wdrożenia i audytu, bez automatycznego dziedziczenia RLS; ryzyko zapytań N+1, jeśli każda zagnieżdżona relacja wyzwala własne zapytanie Postgres bez dyscypliny; oraz dokumentację API, którą należy utrzymywać ręcznie lub za pomocą generatora strony trzeciej w celu integracji.
Jeśli chodzi o surową wydajność, pytanie „Czy Node.js jest wolniejszy od Rusta” jest tematem samym w sobie — nasz artykuł na temat opóźnień Rust vs Node.js omawia to szczegółowo, z metodologią zadeklarowaną wcześniej na naszej stronie metodologii testów porównawczych . Niestandardowy interfejs API ma ten sam profil wydajności, co każda usługa HTTP, z której już korzystasz, ani lepszy, ani gorszy pod względem konstrukcji. Aby dokładnie wiedzieć, gdzie PostgREST nasyca się i w którym momencie konieczna jest warstwa niestandardowa, zobacz nasz artykuł na temat rzeczywistych ograniczeń PostgREST w produkcji.
Tabela porównawcza: trzy opcje obok siebie
Poza architekturą przy wyborze najczęściej pojawiają się cztery kryteria: szybkość wdrożenia, rzeczywista elastyczność biznesowa, długoterminowe zadłużenie techniczne oraz typowy przypadek użycia, w którym każda opcja jest najwygodniejsza.
| Konfiguracja wstępna | Minuty — schemat już istnieje | Godziny — podłącz bazę, skonfiguruj uprawnienia | Dni lub tygodnie — zapisz każdą trasę |
|---|---|---|---|
| Elastyczność biznesowa | Ograniczone do SQL (RPC, wyzwalacze) | Dobre poprzez akcje/wyzwalacze zdarzeń, ale przechodzi przez zewnętrzny webhook | Razem, prosto |
| Terminowy dług techniczny | Słabe — diagram pozostaje jedynym źródłem prawdy | Średni — metadane Hasury, które należy zachować oprócz schematu | Wysoki, jeśli zespół rośnie bez dyscypliny (testy, dokumentacja, przegląd) |
| Typowy przypadek użycia | Direct CRUD na stabilnym schemacie, zespół znający się na SQL | Połącz kilka źródeł danych lub logikę zorientowaną na agenta AI | Złożona logika biznesowa, liczne integracje firm trzecich |
| POSTGREST | HASURA | NIESTANDARDOWE API |
Dokąd zmierza logika biznesowa w projekcie Aurabase?
W projekcie silnika Aurabase Postgres warstwa CRUD jest już objęta rzeczywistą instancją PostgREST, a nie przybliżoną reimplementacją. Pytanie, które pozostaje otwarte dla tego porównania: gdzie napisać to, co wykracza poza CRUD?
Istnieją dwie ścieżki i nie wykluczają się one wzajemnie. Pierwsza: funkcja SQL udostępniona w RPC dla dowolnej logiki, którą można wyrazić w SQL — obliczenie całkowitej sumy, walidacja krzyżowa między kilkoma tabelami, aktualizacje kaskadowe w pojedynczej transakcji.
Drugi sposób: Edge Functions, do wszystkiego, co wykracza poza domenę SQL – wywoływanie API płatności, wysyłanie e-maili, obliczanie osadzania. W Aurabase prowadzą tam dwie ścieżki: edytor Studio, który uruchamia kod Deno (TypeScript) dokładnie tak, jak w Supabase, oraz aura functions deployCLI, którego celem jest osobna ścieżka dla funkcji napisanych w Rust i skompilowanych w WASM — szczegółowo opisanych w naszej zunifikowanej architekturze Rust. Żadna ze ścieżek nie wymaga hostowania oddzielnego serwera Node, w przeciwieństwie do opcji „niestandardowego interfejsu API” opisanej w tym artykule, gdzie za ten serwer odpowiadasz wyłącznie Ty.
Ta dystrybucja nie jest chwiejnym kompromisem pomiędzy trzema porównywanymi tutaj modelami: jest to dosłownie PostgREST dla CRUD, cegiełka zbliżona do Hasura Actions dla logiki zdarzeń za pośrednictwem RPC i wyzwalaczy oraz Edge Functions, które pozwalają uniknąć działania kompletnego serwera aplikacji - bez wymuszania binarnego wyboru pomiędzy „całym PostgREST” a „wszystkimi niestandardowymi”.
Jak wybrać w zależności od kontekstu
Najczęściej pojawiają się cztery sytuacje. Właściwy wybór zależy głównie od wymagań logiki biznesowej, a nie od popularności narzędzia.
- Twój schemat jest stabilny, a logika biznesowa jest w języku SQL. Samoobsługowy PostgREST lub natywnie zintegrowany (Aurabase, Supabase) wystarczy: nic więcej do hostowania, a schemat pozostaje jedynym źródłem prawdy.
- Chcesz połączyć kilka źródeł danych lub Twój plan działania jest nastawiony na agentów AI korzystających z Twoich danych. Hasura z warstwą PromptQL lepiej pasuje do tego terenu.
- Twój produkt ma bogatą logikę biznesową, liczne integracje firm trzecich i zespół wyposażony już w język aplikacji. Niestandardowy interfejs API pozostaje najbardziej bezpośrednim wyborem, kosztem jego napisania i utrzymywania w miarę upływu czasu.
- Chcesz, aby CRUD generował się samodzielnie bez poświęcania rzeczywistej przestrzeni dla logiki biznesowej (RPC, funkcje brzegowe) i bez tworzenia kolejnej usługi aplikacji do wykorzystania. Jest to kąt udokumentowany w tym porównaniu zastosowanym do Aurabase, poprzednia sekcja.