Polyglot microservices rendszerekben mindig ugyanaz a pont fáj: az interfész definíciók. C#-ban megírod az IOrderService-t, aztán átírod Java-ban, aztán Python-ban. Három fájl, három helyen karbantartva, és előbb-utóbb az egyik elcsúszik a másiktól. A hiba ott üti fel a fejét, ahol a legkevésbé várja az ember — a rendszerhatáron, éles környezetben, ahol a két oldal különböző verziót hív.

A forrás egyetlen legyen

A UniContract erre ad választ. Egy .contract fájlban definiálod az interfészt egyszer, és a tool kigenerálja az összes célplatformra. Nem kézzel szinkronizálsz — a generátor csinálja, és mindig konzisztens marad.

Egy példa arra, hogyan néz ki egy contract definíció:

namespace DataStoring {
    interface IDataStore {
        readonly property Connection: IConnection
        async method IsCollectionExists(name: string) => boolean
        async method GetCollectionByName<T constraint IEntity>(name: string) => ICollection<T>
    }
}

Ebből a definícióból C# interfész, Java interface, Python abstract class generálható — mind ugyanazt a kontraktust valósítják meg, és ha a contract megváltozik, mindenki megváltozik.

A fordítóhoz hasonló pipeline

Az architektúra egy komplett fordítóra hasonlít. ANTLR 4 alapú lexer és parser dolgozza fel a .contract fájlokat, a syntax tree-ből element builder épít szemantikus modellt, a semantic checker validálja az összefüggéseket, majd a pluggable emitterek generálják a célnyelvi kódot.

Az emitterek Python modulok — bárki írhat sajátot anélkül, hogy a core engine-hez nyúlna. Ez teszi bővíthetővé: ha egy új platform kell (Rust, Go, TypeScript), egy új emitter modul elég.

Tervezési döntések

A constraint-alapú generikusok (<T constraint IEntity>) biztosítják, hogy a típusbiztonság megmaradjon minden platformon. Ez nem magától értetődő — Java, C# és Python generikusokat egészen másképp kezelnek, de a contract szintjén egységes szemantikát ad.

Az async kulcsszó a contract-ban automatikusan Task-ot generál C#-ban, Promise-t TypeScript-ben, async def-et Python-ban. Nem kell minden platformon külön dönteni — a contract megmondja, mi aszinkron.

Az import rendszer lehetővé teszi, hogy a contractok egymásra hivatkozzanak. A PolyPersist például UniContract definíciókat használ az összes store interfészhez — ez garantálja, hogy a C# és a többi platform implementációja konzisztens marad.

Hol használom?

A PolyPersist összes cross-platform interfészét UniContract generálja. A D3I szintén támaszkodik rá az emitter outputok konzisztenciájához. Mindenütt, ahol több platformon kell ugyanazt a kontraktust megvalósítani, a UniContract adja az egységes forrást.