Development
Contribute to GonexmainFramework internals
Development snapshot · main · No release published yet.
FOR FRAMEWORK CONTRIBUTORS

Framework internals

Understand Gonex internals: application registration, transport contracts, adapters, package dependencies and generator ownership.

goNex uses explicit registration and ordinary Go composition. Its business core is independent of HTTP, RPC and persistence adapters.

Dependency direction

Business services live in modules/NAME/service.go and use plain Go values plus small interfaces owned by the consumer. HTTP adapters own schemas and request mapping; GORM repositories and gRPC clients implement business interfaces at their boundaries. Services should not import Gin, GORM, gRPC, Protobuf or transport DTOs.

mermaid
flowchart LR
    HTTP[HTTP adapter] --> Service[Business service]
    RPC[gRPC server adapter] --> Service
    Service --> Port[Local dependency interface]
    Database[GORM repository] -. implements .-> Port
    Client[gRPC client adapter] -. implements .-> Port

Registration and lifecycle

A module receives registration capabilities, never ownership of a listener. Registration is explicit, ordered and atomic per App.Register call. The application owns listeners and managed resources. Startup failures close started resources; shutdown drains HTTP and closes resources in reverse order. Stopped applications cannot restart.

Dependencies register before consumers. Context-aware resource lifecycles make background work and cleanup explicit. See modules and lifecycle.

HTTP and RPC boundaries

HTTP is unversioned by default. OpenAPI projects the registered typed endpoints. Independent versioned HTTP adapters can share one core service; legacy routes remain unless replacement is explicit.

gRPC is opt-in and has no default listener. Protobuf packages and Go paths carry their API major. Contracts use a separate Go module so services can depend on a shared wire contract without importing each other's business code.

Generator ownership

Generators own marked registries and record hashes in .gonex.json. They plan and validate writes first, reject handwritten destination collisions and support dry runs. Runtime composition does not scan source or depend on a dependency-injection container.

Independent services have their own Go modules, configuration and migrations. A local go.work file is a development convenience; production dependencies must resolve independently.

Dependencies

The framework is not dependency-free. The root go.mod declares 10 direct dependencies; indirect dependencies are recorded separately in go.mod and go.sum. Optional integrations share the module dependency graph, but HTTP-only applications need not import or start database/RPC adapters.

Direct dependencyResponsibility
github.com/gin-gonic/ginHTTP routing and middleware
github.com/go-playground/validator/v10Typed input validation
github.com/santhosh-tekuri/jsonschema/v6Offline OpenAPI schema validation
github.com/ncruces/go-sqlite3/gormliteCGO-free SQLite integration
gorm.io/driver/postgresPostgreSQL driver
gorm.io/gormOptional persistence adapter
google.golang.org/grpcOptional RPC transport
google.golang.org/protobufProtobuf runtime and generation support
github.com/bufbuild/protocompileContract compilation tooling
golang.org/x/modGo module validation and generator edits

The list above groups responsibilities; the actual source of truth is go.mod, including any separate module requirements. Check its first require block when updating the dependency badge.

Design decisions and limits

Prefer small consumer-owned interfaces and explicit constructors over global registries. Keep validation and the exported contract coherent, rather than silently projecting unsupported DTO behavior. Keep migrations explicit and immutable.

Service discovery is static, cancellation is cooperative and generators do not invent business mappings. See API decisions, upgrade policy and release scope.