Ten plik dokumentuje tę architekturę w jej rzeczywistej postaci w kodzie, weryfikowanym plik po pliku na dzień 23 sierpnia 2026 r. — zawiera diagramy, rysunki i fragmenty. To jest główna strona klastra „Rust Engineering”: zawiera przegląd i linki do szczegółowych analiz technicznych (Axum, obszar roboczy Cargo, bramka, PostgREST, pg_graphql i reszta pliku) opublikowanych lub będących w trakcie publikacji. Pełne porównanie produktów z konkurencyjnym BaaS można znaleźć w naszym porównaniu Aurabase z Supabase.
Najważniejsze
- Pojedynczy ładunek Workspace: 18 skrzynek (11 usług biznesowych,
auraCLI, 5 współdzielonych bibliotek, Rust SDK) skompilowanych razem przez pojedynczycargo build --workspace. - Kod biznesowy waży około 274 000 linii rdzy (mierzone za pomocą
find+wc -l, 23 sierpnia 2026 r.), rozmieszczonych w tych 18 skrzyniach. - Brama (
aura-gateway) oddziela dwie płaszczyzny — dane (SDK, port 8080) i zarządzanie (Studio, port 8090) — każda z własnym stosem oprogramowania pośredniego i uwierzytelnianiem. - Aurabase nie przepisuje PostgREST: prawdziwy plik binarny nadrzędny (v12.2.8) działa na dzierżawcę, zorganizowany przez usługi Rust — wartość dodana jest wokół niego, a nie zamiast tego.
- Jedyne zauważalne odejście od czystego Rusta: domyślne środowisko wykonawcze Edge Functions (tryb
deno) to dedykowana usługa TypeScript oparta na izolacji V8; druga ścieżka, natywna i w Rust poprzez Wasmtime, istnieje dla trybuwasm.
Co odróżnia Aurabase od usługi BaaS składanej po usłudze
Większość Postgres BaaS typu open source oferuje swoje usługi w wielu językach. To nie jest ocena wartościująca — to fakt architektoniczny, który ma konkretne konsekwencje: tyle łańcuchów kompilacji, konwencji błędów i logiki uwierzytelniania należy zachować w synchronizacji, ile jest używanych języków.
W Aurabase warstwa produktów, którą sami piszemy i utrzymujemy — brama, uwierzytelnianie, baza danych, czas rzeczywisty, pamięć masowa, powiadomienia, sztuczna inteligencja, udostępnianie, zarządzanie kontami — to pojedynczy obszar roboczy Cargo, jeden język, pojedynczy łańcuch kompilacji. Jest to wybór dokumentowany w tym pliku.
„Ujednolicony rdzeń” nie oznacza, że wszystko, co działa w środowisku produkcyjnym, to rdza. Jak każdy Postgres BaaS, Aurabase również opiera się na elementach konstrukcyjnych open source, których nie napisał: sam PostgreSQL, PostgREST, NATS. Różnica strukturalna w przypadku heterogenicznego stosu nie dotyczy tych wspólnych elementów składowych — dotyczy warstwy produktu, która je koordynuje. W poniższych sekcjach szczegółowo opisano, gdzie dokładnie przebiega ta granica, łącznie z jedynym prawdziwym wyjątkiem, który znaleźliśmy podczas kontroli kodu (Funkcje krawędziowe, sekcja 09).
18 skrzynek, jeden łańcuch kompilacji
Korzeń Cargo.toml deklaruje obszar roboczy Cargo w programie rozpoznawania nazw v2 z 18 elementami: 11 usług biznesowych, aura-cliCLI, 5 bibliotek współdzielonych i aurabase-rsSDK. Oto rzeczywista lista, która pojawia się w repozytorium.
Wspólne zależności działają w [workspace.dependencies]: Axum 0.8 (z WebSockets, wieloczęściowym, makrami), Tokio, Tower/Tower-HTTP, SQLx 0.8 (Postgres + MongoDB przez mongodb dla dodatkowego silnika NoSQL), async-nats 0.47, sqlparser 0.53 (weryfikacja SQL NL2SQL), oauth2 5, jsonwebtoken 10 i dwie biblioteki wydajnościowe występujące w prawie każdej usłudze: mimalloc jako globalny alokator i moka/dashmap dla pamięci podręcznej w pamięci.
Profil wydania dokumentuje zakładany wybór: panic = "unwind" zamiast "abort". Komentarz do pliku jest oczywisty — panika w programie obsługi Axum/Tokio jest izolowana przez środowisko wykonawcze (żądanie, którego to dotyczy, zwraca 500), zamiast zatrzymywać cały proces i odcinać konkurencyjne żądania. Zgodnie z tą samą uwagą, wzrost wydajnościabort (około 1 do 2% RPS) nie jest wart utraty izolacji. Jest to kompromis między niezawodnością a szybkością udokumentowany w kodzie, a nie twierdzenie marketingowe.
Całość kompiluje pojedynczy cargo build --workspace. Pojedynczy cargo test --workspace uruchamia cały zestaw testów. Pojedynczy cargo clippy --workspace --all-targets -- -D warnings powoduje, że cały produkt podlega tym samym zasadom. Szczegóły tej struktury - dziedziczenie zależności, wewnętrzny graf pomiędzy bibliotekami i usługami, pułapki, które napotkaliśmy podczas jej rozwijania - są tematem dedykowanego artykułu: Architektura obszaru roboczego Cargo, jak zbudować wielousługowy backend Rusta.
Linie rdzy według usługi (znajdź usługi -nazwa „*.rs” | xargs wc -l, 23 sierpnia 2026 r.):
kontrola aury
36 024
aura-db
30 255
aura-auth
28 431
dostawca aury
28 271
powiadomienia aurowe
18 498
będzie miał
18 305
brama aury
16 938
aura w czasie rzeczywistym
16 799
magazynowanie aury
13 747
funkcje aury
11 619
wędrowiec aury
538
Z wyłączeniem wspólnych bibliotek (adaptery aura-db: 24 725 linii, aura-core: 7259, aura-migrations: 3641, aura-crypto: 2718, aura-telemetry: 201), CLI (aura-cli: 9845) i Rust SDK (aurabase-rs: 6363). aura-migrator, jednorazowe zadanie migracji, a nie długotrwały serwer HTTP, celowo pozostaje najmniejszą usługą w obszarze roboczym.
11 usług biznesowych, każda jako samodzielny serwer Axum
Każda usługa jest niezależnym plikiem binarnym Axum/Tokio z własną konfiguracją i portem. Dziesięć z jedenastu eksponuje /health i /metrics i deklaruje mimalloc jako globalny alokator — jedyny wyjątek, aura-migrator, to zadanie jednocelowe, a nie stale działający serwer.
| brama aury | Brama dwupłaszczyznowa (dane: 8080, zarządzanie: 8090): proxy dla wszystkich innych usług. |
|---|---|
| aura-auth | Uwierzytelnianie: JWT, 15 nazwanych dostawców OAuth + ogólny OIDC na projekt, sesje, MFA. |
| aura-db | Interfejs API bazy danych: zarządzanie/przeładowywanie PostgREST na dzierżawcę, adaptery Postgres i MongoDB, CDC. |
| dostawca aury | Cykl życia projektu: dedykowane lub współdzielone klastry CNPG, role, PostgREST na najemcę. |
| aura w czasie rzeczywistym | WebSocket i SSE, transmisja CDC, obecność między instancjami za pośrednictwem NATS JetStream KV. |
| magazynowanie aury | Obiekty kompatybilne z S3 (MinIO), zasady RLS przenoszone z Postgres. |
| funkcje aury | Funkcje Edge: wdrożenie, zadania, cron, natywne środowisko wykonawcze Wasmtime (patrz sekcja 09). |
| powiadomienia aurowe | E-mail, push, wychodzące webhooki. |
| będzie miał | Brama NL2SQL, RAG i LLM (natywny OpenAI, Anthropic, Gemini + dowolny punkt końcowy zgodny z OpenAI). |
| wędrowiec aury | Silnik migracji: pojedyncze źródło schematu przechowywania odtwarzane przy każdym udostępnianiu. |
| kontrola aury | Plan zarządzania: konta programistów, organizacje, rozliczenia, Studio API. |
Interfejs CLI aura (≈ 9800 linii) komunikuje się z tymi samymi interfejsami API, co zestawy SDK — nie ma uprzywilejowanej ścieżki. Pełne odniesienia do każdej usługi znajdują się w dokumentacji architektury i dokumentacji CLI .
5 skrzynek, które zapobiegają dryftowi między usługami
W stosie poliglotów reguła bezpieczeństwa — format błędu, ochrona SSRF, ograniczenie szybkości — musi zostać ponownie zaimplementowana w każdym języku i prawie zawsze zmienia się z upływem miesięcy. Aurabase koduje go raz, w bibliotece obszaru roboczego, wykorzystywanego przez wszystkie zainteresowane usługi.
| rdzeń aury | 7 259 l. | Współdzielone elementy podstawowe: błędy, koperta odpowiedzi API, oświadczenia JWT, wewnętrzne uwierzytelnianie między usługami, pomocnicy NATS, ograniczanie szybkości, klient HTTP chroniony SSRF, wyłącznik automatyczny, rozwiązywanie dzierżaw, pomiary. |
|---|---|---|
| adaptery aura-db | 24 725 l. | Cecha umożliwiająca dostosowanie ujednoliconych baz danych, implementacji Postgres i MongoDB używanych przez aura-db. |
| aura-krypto | 2 718 l. | Hashowanie haseł, generowanie tokenów, podpisywanie/weryfikacja JWT, szyfrowanie na poziomie pola. |
| migracje aury | 3 641 l. | Silnik migracji — pojedyncze źródło schematu dzierżawy odtwarzane przez dostawcę usług (nie migracje/określone foldery dla każdej usługi). |
| aura-telemetria | 201 l. | Konfiguracja OpenTelemetry + śledzenie, współdzielona przez 11 usług. |
Bezpośredni skutek: poprawka bezpieczeństwa w aura-core — na przykład ochrona SSRF — rozprzestrzenia się na każdą usługę konsumencką w następnym cargo build, a nie poprzez pięć oddzielnych poprawek w pięciu językach.
Plan podwójny: ruch SDK kontra ruch Studio
aura-gateway oddziela dwie powierzchnie, które nie mają ani tych samych klientów, ani tego samego modelu uwierzytelniania. Płaszczyzna danych (port 8080, zmienna GATEWAY_PORT) odbiera ruch SDK/aplikacji uwierzytelniany kluczem API (apikey, X-API-Key lub ?apikey=). Płaszczyzna zarządzania (port 8090, MANAGEMENT_PORT) odbiera ruch Studio/administracyjny uwierzytelniany przez konsolę JWT (Authorization: Bearer).
Każda płaszczyzna zawiera własny stos oprogramowania pośredniczącego — identyfikacja zapytań, dziennik dostępu, limit szybkości, uwierzytelnianie (specyficzne dla płaszczyzny), wyłącznik automatyczny, a następnie serwer proxy — zaimplementowany w oddzielnych modułach (middleware/rate_limit.rs, middleware/circuit_breaker.rs, middleware/auth_data_plane.rs, middleware/auth_management_plane.rs), a nie w pojedynczym łańcuchu przypadkowo współdzielonym między dwiema powierzchniami, które nie powinny ufać sobie nawzajem w ten sam sposób. sposób.
Dokładna kolejność oprogramowania pośredniczącego, ograniczenie szybkości na cel i serwer proxy NATS/HTTP są tematem osobnego artykułu: brama dwupłaszczyznowa, zaprojektuj bramę API płaszczyzny danych/płaszczyzny zarządzania w Rust.
Dlaczego Aurabase nie implementuje ponownie PostgREST w Rust
Wygenerowany samodzielnie interfejs API REST, z którego korzysta zestaw SDK, nie jest wewnętrznym modułem Rusta: jest to prawdziwy plik binarny nadrzędny PostgREST (postgrest/postgrest:v12.2.8), wdrożony w 2 replikach na dedykowany projekt (deploy/cnpg/tenant-postgrest.yaml), umieszczony w kolokacji z instancją CNPG dzierżawcy. aura-provisioner tworzy to wdrożenie, a aura-db sonduje jego punkt końcowy OPTIONS po każdym ponownym załadowaniu schematu, aby potwierdzić, że PostgREST wziął pod uwagę zmianę DDL.
Jest to założony wybór architektoniczny, a nie skrót: PostgREST jest dojrzałym, powszechnie przyjętym projektem, którego przepisywanie krok po kroku w Rust nic by nie dało. Praca Aurabase w Rust koncentruje się wokół — routingu dla wielu dzierżawców, udostępniania, izolacji sieci przez NetworkPolicy, współdzielonego uwierzytelniania z bramą, zorganizowanego przeładowywania schematu — a nie na samym silniku zapytań. Co tak naprawdę obejmuje ta kompatybilność i gdzie się kończy, jest tematem osobnego artykułu: PostgREST, rzeczywista kompatybilność ialternatywy.
Ta sama logika po stronie GraphQL: rozszerzenie Postgres pg_graphql (prekompilowany pakiet .deb, v1.6.1) jest instalowane w dedykowanym obrazie CNPG i aktywowane na żądanie dla każdego projektu poprzez punkt końcowy POST /v1/control/projects/{project_id}/graphql/enable — nie jest to również przepisany silnik GraphQL. Szczegóły i uczciwe porównanie z Hasurą i PostGraphile: Natywne API GraphQL na Postgres z pg_graphql.
RLS i rola uwierzytelniająca, a nie warstwa aplikacji
Izolacja wielu dzierżawców nie opiera się na filtrze WHERE tenant_id = ? dodanym przez ORM aplikacji: każde żądanie przechodzi przez rolę aura_authenticator, która przed wykonaniem żądania wykonuje transakcję SET LOCAL ROLE tenant_<uuid> — dokładnie taki model, jakiego oczekuje sam PostgREST. Zabezpieczenia na poziomie wiersza zajmują się resztą na poziomie silnika, a nie na poziomie kodu biznesowego.
Nie wszystkie projekty mają tę samą topologię Postgres. Kod aura-provisioner udostępnia typ ProjectInstanceKind z co najmniej dwoma rzeczywistymi wariantami: FullyDedicated (instancja CNPG w całości dedykowana projektowi) i SharedClusterDedicated (schemat izolowany przez RLS we współdzielonym klastrze CNPG). Abonamentowy plan określa topologię – nie jest to jednolita obietnica „dedykowanej bazy dla każdego”.
Zagadnienie „dlaczego dedykowana baza na projekt, a nie tylko izolacja aplikacji” jest tematem dedykowanego artykułu: RLS i dedykowana baza na projekt. Dokumentacja zabezpieczeń na poziomie wiersza obejmuje praktyczne wdrożenie.
Rdzeń NATS, a nie JetStream: asynchroniczna komunikacja między usługami
Dziesięć z jedenastu usług biznesowych deklaruje async-nats jako bezpośrednią zależność w ich Cargo.toml — tylko aura-migrator radzi sobie bez niej. Czego ta nazwa skrzynki nie mówi: te usługi prawie wszędzie korzystają zpodstawowego API pub/sub API firmy NATS (Client::publish / publish_with_headers, dostawa co najwyżej jednorazowa bez utrwalania i odtwarzania), a nie JetStream. Jest to przypadek zweryfikowany w kodzie dla trzech najważniejszych zastosowań: dystrybucja CDC PostgreSQL do aura-realtime, powiadamianie o zadaniach Edge Functions w aura-functions (sama DLQ mieszka w Postgres, a nie w NATS) oraz zdarzenia udostępniania między aura-provisioner a resztą floty.
JetStream — tryb trwałości NATS i nazwanych strumieni — pojawia się tylko w jednej zweryfikowanej lokalizacji w monorepo: obecność między instancjami KV Store w aura-realtime (zasobnik aura_presence, magazyn pamięci, 60-sekundowy max_age), który synchronizuje, kto jest podłączony do którego kanału w wielu instancjach ws-front — współdzielony stan między instancjami, a nie strumień zdarzeń do odtworzenia. W innym miejscu obszaru roboczego nie znaleziono żadnych trwałych strumieni JetStream. Szczegóły rurociągu CDC - wal2json, wybór unikalnego cdc-worker przez Lease Kubernetes, rozwinięcie rdzenia NATS do replik ws-front, ponowna weryfikacja RLS przez subskrybenta - są tematem dedykowanego artykułu: transmitował CDC PostgreSQL z NATS. Dokumentacja Realtime opisuje użycie po stronie SDK.
Funkcje Edge: dwa środowiska wykonawcze dla dwóch potrzeb
To najważniejszy niuans tego pliku i jedyne realne odejście od czystej rdzy w kodzie produktu Aurabase. Każda funkcja zawiera pole runtime o wartości "wasm" lub "deno". Procedura obsługi wywołania wybiera odpowiednio ścieżkę wykonania — rzeczywisty fragment, zakomentowany w samym kodzie:
Tryb wasm jest natywny: aura-functions zależy bezpośrednio od Wasmtime (wersja 43, funkcje async i cranelift) i wykonuje moduł w tym samym procesie Rust, z zliczaniem paliwa, przerwami według epoki i ograniczaniem pamięci poprzez StoreLimits. Tryb deno — ten używany domyślnie w edytorze Studio, zapewniający niemal bezpośrednią zgodność Deno.serve() z istniejącym kodem Supabase — deleguje wykonanie do aura-edge-runtime, osobnej usługi TypeScript składającej się z około 550 linii, jawnie modelowanej — sam komentarz nagłówka pliku źródłowego go cytuje — w supabase/edge-runtime (Licencja MIT), która izoluje każde wywołanie do własnego izolatu V8.
Kontrola — wdrażanie, uprawnienia, zadania, cron, przydziały — pozostaje całkowicie w Rust w aura-functions. Dopiero wykonanie kodu użytkownika w trybie deno powoduje wyjście z pliku binarnego Rust. Jest to możliwy do obrony kompromis inżynieryjny (izolaty V8 są tym, co Deno natywnie zapewnia dla tego poziomu sandboxingu), a nie pominięcie, o którym wolimy milczeć. Porównanie Wasmtime vs Wasmer i analiza zimnego startu WebAssembly, które wkrótce pojawią się w tym pliku, pójdą dalej na ten temat.
Dokumentację instruktażową dotyczącą obu ścieżek wdrażania można znaleźć w artykule Funkcje brzegowe. Aby zapoznać się z podręcznikiem migracji Deno z Supabase, zobacz Migracja projektu Supabase do Aurabase, który już udokumentował to rozróżnienie przed tym plikiem.
Co to zjednoczone serce konkretnie zmienia dla ciebie
Jeśli po prostu wywołasz interfejs API za pośrednictwem pakietu SDK, ta architektura będzie niewidoczna — taki jest cel. Ma to znaczenie głównie dla trzech odbiorców: tych, którzy oceniają niezawodność operacyjną backendu obsługującego wielu dzierżawców przed migracją do niego danych produkcyjnych, tych, którzy planują wnosić wkład do repozytorium (MIT, pojedyncze repozytorium) oraz tych, którzy chcą zrozumieć, dlaczego łatka bezpieczeństwa po stronie Aurabase rozprzestrzenia się szybko, a nie wolno.
Konkretnie: pojedynczy układ scalony (cargo build --workspace, cargo test --workspace, cargo clippy --workspace --all-targets -- -D warnings) pokrywa 90% lub więcej powierzchni produktu. Przegląd kodu w aura-core potencjalnie wpływa na dziesięć usług jednocześnie — na lepsze (poprawka nie ginie po drodze) i na gorsze (słabo izolowana zmiana rozprzestrzenia się równie szybko). To kompromis, a nie magiczne rozwiązanie — i właśnie dlatego dokumentujemy rzeczywistą architekturę, a nie streszczenie marketingowe.
Pozostała część pliku Rust Engineering
Na tej stronie filarowej znajdują się łącza do analiz technicznych klastra w chwili ich publikacji. Aktualny stan w momencie publikacji tej strony — linki stają się aktywne, gdy tylko odpowiedni artykuł pojawi się online.
Klaster A — Struktura i architektura
Axum vs Actix-web: jaki framework dla backendu Rust w środowisku produkcyjnym?Opublikowano
Architektura przestrzeni roboczej Cargo: jak zbudować wielousługowy backend w RustOpublikowano
Brama dwupłaszczyznowa: projektowanie bramy API płaszczyzny danych/płaszczyzny zarządzania w RustOpublikowano
Klaster B — samodzielnie wygenerowany interfejs API w Postgres
PostgREST: co naprawdę obejmuje kompatybilność i jakie istnieją alternatywyOpublikowano
Natywny interfejs API GraphQL na Postgres z pg_graphql: czego Hasura i PostGraphile nie robią tego samegoOpublikowano
RLS i dedykowana podstawa dla każdego projektu: wybór izolacji dla wielu najemców z AurabaseOpublikowano
Klaster C — czas rzeczywisty i przesyłanie wiadomości
Dystrybucja PostgreSQL CDC za pomocą NATS: architektura czasu rzeczywistegoOpublikowano
Klaster D — Funkcje brzegowe WebAssembly
| Wasmtime vs Wasmer: które środowisko wykonawcze WebAssembly dla funkcji Edge w środowisku produkcyjnym | Już wkrótce |
|---|---|
| Funkcje Edge w Rust/WASM w porównaniu z Cloudflare Workers i Vercel Edge | Już wkrótce |
| Zimny start WebAssembly: co naprawdę mówią testy porównawcze (a czego jeszcze nie możemy powiedzieć) | Już wkrótce |
Klaster E — Migracja i alternatywy
Przeprowadź migrację projektu Supabase do Aurabase bez przepisywania zasad RLSOpublikowano
Suwerenny hosting własny: pozycjonowanie Aurabase w porównaniu z natywnym dla Rust BaaJuż wkrótce