Kezdő lépések

Bevezetés

Mi a gpsystem, kinek szól, és mi marad a te kezedben.

A gpsystem 12 önálló Go-modul plusz egy vékony generátor/kit, ami ezeket összeköti:

  • 12 önálló modul, mindegyik saját Go-modul, külön verziózva és publikusan tagelve (v0.1.0), önmagában is használható bármely Go-programban: errs (stackelhető hibák), envconf (típusos konfiguráció), httperr (+ httperr/validate), dbx (+ dbx/pg, dbx/bunx, dbx/seed), paginate, queue, events (+ events/outbox, events/scheduler), auth (+ auth/rbac, auth/policy), mail (+ mail/smtp, mail/mjml), notify (+ notify/database, notify/broadcast), storage (+ storage/local, storage/driver/s3), telemetry (+ telemetry/logx, telemetry/otelx, telemetry/sentryx).
  • Egy vékony kit (github.com/gp-system/gpsystem): négy chassis-csomag, ami futó service-szé komponálja a modulokat (app életciklus, server chi/net-http-n, worker asynq-on, realtime centrifuge-on), plusz egy CLI (go tool gpsystem), ami projektet, modult, surface-t, handlert, eventet, listenert és jobot vázol fel, a hozzájuk tartozó TypeSpec kontraktusfájlokkal együtt.

Miért létezik

A Go-ökoszisztéma ereje a kis, egymástól független, jól tesztelt library-kben van. Cserébe minden projekt elölről végigcsinálja ugyanazt a tíz döntést: melyik logger, hogyan néz ki a graceful shutdown, hogyan modellezed a hibákat, hogyan lépi át egy tranzakció a repository-határokat. A gpsystem ezt a munkát végzi el egyszer, mindenki helyett: a bevált Go-library-ket húzza össze egyetlen, karbantartott kompozícióba, szétosztva a fenti 12 modul közt, ahelyett hogy sajátot írna helyettük.

PHP-s háttérrel érkezel? A Laravelből érkezőknek és a Symfonyból érkezőknek oldal fogalomról fogalomra megfelelteti a két világot.

A modulok lefedik az összes alapfunkcionalitást, amivel a legtöbb oldalon találkozol, a kit pedig futó service-szé köti össze őket:

Mindegyik egyszer van megírva és tesztelve a kitben; a projektjeid egyetlen go.mod-verzió emelésével frissülnek.

Mi NEM a gpsystem

  • Nem framework. Nincs IoC-konténer, nincs kötelező Module-interfész, nincs kit-tulajdonú lifecycle-hook, amit egy bootstrap felfedez és meghív. A main()-t te írod; minden függőség kézzel, explicit kóddal kerül be. A kit egyetlen inverziója a folyamat-életciklus (Run(ctx, cfg, register)): jelez, leállít, flush-öl, a business-wiringhez nem nyúl. Lásd az Architektúra oldalt, hol húzódik ez a határ.
  • Nem platform. A gpsystem nem birtokolja az infrastruktúrádat: nincs saját deploy-modell, saját felhő, saját runtime; a chi.Router, a pgx pool a tiéd marad.
  • Nem ORM. Nincs Eloquent- vagy Doctrine-szimuláció; a repository-réteg SQL-t (pgx) vagy egy query buildert (bun) ír, explicit lekérdezésekkel.
  • A generált kód a tiéd. Amit a CLI felvázol, azt úgy szerkeszted, mint bármely más kódot, kivéve a szűk, kimondottan újragenerált zónát (a TypeSpec→OpenAPI→oapi-codegen transport-stubok a gen/ alatt), amit nem kézzel írsz, hanem a specifikációt módosítod.

Nem rejti el a függőségeket

A gpsystem elve: centralizál, nem absztrahál. A külső függőségekhez való hozzáférés egy-egy modulban összpontosul, de a típusaik szabadon átfolynak a publikus API-n:

  • a server.Run register-függvénye chi.Router-t ad: a handlereid a natív net/http API-t használják;
  • a dbx/pg pgx.Rows-t és pgxpool.Pool-t ad vissza, a dbx/bunx bun.DB-t;
  • a queue *asynq.Task-kal dolgozik, a worker escape hatch-ei (WithAsynqConfig, WithMux) nyers asynq-ot adnak.

Az upstream dokumentáció és a Stack Overflow-válaszok emiatt nálad is érvényesek maradnak, és nem egy kit-specifikus wrapper-API-t kell megtanulnod. Három helyen tér el ettől a gpsystem, mindháromszor kimondott okkal:

  • a storage modul Driver/Disk felosztása elrejti az AWS SDK-t egy kis backend-kontraktus mögé: az app-kódodnak így nem kell az AWS SDK-t importálnia egy fájlfeltöltéshez;
  • a telemetry/sentryx becsomagolja a sentry-go-t: a Sentry env-ből kapcsolható (SENTRY_DSN üresen = teljesen kikapcsolva), és aki nem használja, annak a binárisába be sem linkelődik;
  • a mail Mailer interfésze mögött él a go-mail és az mjml-go, így tesztben memória-mailerre cserélhető.

A részek cserélhetőek és elhagyhatóak: a dbx/pg használható a server nélkül (pl. egy CLI-eszközben), a Sentry és az OTel env-vel kikapcsolható, a pgx/bun importtal választható, minden modul a többi nélkül is használható. Az Architektúra oldal modulonként mutatja, mi mitől függ.

A ~15 soros main.go

Egy modul belépési pontja ennyi (a graceful shutdown, a telemetria, a hibarenderelés és a validáció már be van kötve):

cmd/shop/main.go
func main() {
    cfg := envconf.MustLoad[config.Config]()
    ctx := context.Background()
    pool := pg.MustNewPool(ctx, cfg.DB)

    err := server.Run(ctx, cfg.Server, func(r chi.Router) error {
        api := chi.NewRouter()
        deps := shop.Dependencies{
            DB:         pg.NewDB(pool),
            Transactor: pg.NewTransactor(pool),
        }
        shop.RegisterApi(api, deps)
        shop.RegisterAdmin(api, deps)
        r.Mount("/api/v1", api)
        return nil
    }, server.WithCloser("pgxpool", func(context.Context) error {
        pool.Close()
        return nil
    }))
    if err != nil {
        log.Fatal(err)
    }
}

Ez a shop mintaalkalmazás belépési pontja. A dokumentáció példái végig erre a projektre épülnek.

Mi marad a te kezedben

  • A router API-ja natív marad. A handlereid a net/http http.ResponseWriter/*http.Request-jét kapják (vagy egy generált handlerben a codegen típusos request/response-át); a server.Run middleware-t és életciklust köt be, de nem csomagolja be a routingot vagy a kéréskezelést. Amit a chi és a net/http tud, azt az appod is tudja.
  • A generált kód a tiéd. A váz a te repódban landol, és úgy szerkeszted, mint bármely más kódot. A generátorok soha nem írnak felül meglévő fájlt, és csak megjelölt anchor-pontokhoz (// gpsystem:*) nyúlnak. Nincs runtime, ami a projektedet értelmezné.
  • Szándékosan vékony. A server.Run a signal.NotifyContext, a listen, a drain és egy rendezett cleanup-lista kompozíciója (az engine-agnosztikus app életciklus), pont az a kód, amit egyébként service-enként megírnál, csak egy helyen karbantartva.

Egy fogyasztó projekt alakja

Minden modul saját belépési pontot kap (cmd/<modul>/main.go) és saját processzként fut. Külön vagy együtt deployolod, ahogy akarod. Az API kontraktus spec-first: a TypeSpec OpenAPI 3.0-ra fordul, abból szigorú, típusos szerver-interfész generálódik chi felett. A handlered egy generált interfészt implementál, így a spec-eltérés fordítási hiba.

Merre tovább

Copyright © 2026