Ha az alkalmazáskódnak tudnia kell, hogy MongoDB vagy Cassandra van mögötte — az tervezési hiba. Nem feltétlenül katasztrófa, de hiba. Az üzleti logika ne függjön az infrastruktúra döntéstől. A PolyPersist ezt az elvet valósítja meg .NET-ben, egységes interfészeken keresztül, dokumentum-, oszlop- és blob tárók fölött.

Mi a probléma pontosan?

Az ORM-ek részben megoldják ezt a kérdést, de csak az SQL világban. Ha egy projekt MongoDB-t használ dokumentumokhoz, Cassandrát idősoros adatokhoz, és S3-at fájlokhoz — mindegyikhez külön hozzáférési réteget kell írni. Ezek nem kompatibilisek egymással, nem cserélhetők, és minden projekt újra megírja ugyanazt.

A cloud-agnosztikus fejlesztés ráadásul elvárja, hogy ne legyen mélyen bele­égetett Azure vagy AWS függőség az üzleti logikába. Ez elvben helyes, de megvalósításhoz egységes interfészek kellenek. A PolyPersist ezeket adja.

Hogyan működik?

A könyvtár három store típust absztrahálja:

  • DocumentStore — MongoDB, in-memory (fejlesztéshez, teszteléshez)
  • ColumnStore — Cassandra, Amazon Redshift, Google BigQuery
  • BlobStore — Azure Blob, Amazon S3, Google Cloud Storage, MinIO, GridFS, FileSystem

A fogyasztó kód csak az interfészekkel dolgozik (IDocumentStore, IBlobStore, IColumnStore). Az, hogy mögötte MongoDB vagy in-memory implementáció fut, dependency injection szinten dől el — nem a kódban. Ez lehetővé teszi, hogy teszteléshez in-memory, production-ban Mongo fusson, anélkül, hogy az üzleti logikához nyúlna bárki.

Multiplatform interfészek

A PolyPersist nem csak C#-ban él. Az összes store interfész definícióját a UniContract tool generálja — ez garantálja, hogy a IDocumentStore, IBlobStore és IColumnStore kontraktus pontosan ugyanaz C#-ban, Java-ban és Python-ban. Ha az interfész változik, mindenki változik egyszerre.

Ez azt jelenti, hogy egy Java-ban írt service ugyanazon a kontraktuson dolgozik, mint egy C# microservice — anélkül, hogy kézzel kellene szinkronizálni a két definíciót. A multiplatform konzisztencia nem emberi fegyelem kérdése, hanem a toolchain biztosítja.

Tervezési döntések, amelyek számítanak

Az ETag alapú optimista zárolás minden entitásnál, minden adatbázisnál egységes. Ez nem magától értetődő — Cassandra és MongoDB egészen máshogy kezelik a konkurenciát. Az egységesítés kompromisszumot jelent, de a fogyasztó kód szempontjából ez a helyes döntés.

Minden entitáson van PartitionKey. Ez Cosmos DB-vel és DynamoDB-vel való kompatibilitás miatt kell — de ha nem kell, egyszerűen üresen marad. Jobb, ha ott van és nem kell, mint ha kell és nincs ott.

Async-first a tervezés. Minden operáció Task-alapú. Adatbázis-hozzáférés mindig I/O bound — a szinkron API csak problémákat okoz hosszabb távon.

Az interfészek definícióját a UniContract tool generálja — ez biztosítja, hogy a C#, Java és Python implementációk konzisztensek maradjanak egymással.

Mire jó ez a gyakorlatban?

Elsősorban három helyzetben értékes: ha el akarod kerülni a cloud provider lock-in-t az adatkezelési rétegben; ha különböző projektek különböző adatbázisokat használnak, de egységes fejlesztői élményt akarsz; vagy ha tesztelés során in-memory implementációval akarsz dolgozni, éles kódban pedig valódi adatbázissal.

Nem cél, hogy minden adatbázis ugyanolyan legyen — különbségek vannak, és számítanak. De a különbségek az implementációs rétegbe tartoznak, nem az üzleti logikába. Ezt az elvet valósítja meg a PolyPersist.