gortexa

module
v0.26.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 4, 2026 License: MIT

README

Gortexa

Go Status AI generated

A contract-first, batteries-included gRPC framework for Go 1.26. Protobuf is the single source of truth; one h2c port multiplexes three protocols:

  • gRPC (native, over cleartext HTTP/2)
  • HTTP/JSON via grpc-gateway (google.api.http annotations)
  • MCP (Model Context Protocol, Streamable HTTP) for AI agents

…all sharing one interceptor chain, one error model, and one auth path.

Highlights

  • Single-port multiplexing — Content-Type / path dispatch on native h2c (http.Server.Protocols, no deprecated x/net/h2c). External gRPC rides grpc-go's ServeHTTP handler mode (Go's HTTP/2 stack), which upstream marks Experimental — a few transport-level features differ from a dedicated gRPC port. Split gRPC onto its own listener (e.g. cmux) if you need grpc-go's full transport semantics on the external surface.
  • Fixed-order interceptor chain (recover → request-id → logger → load-shed → rate-limit → circuit-breaker → auth → validation), fail-loud if incomplete. OTel is a StatsHandler, covering unary and streaming.
  • One error model, three transports — a single mapping table drives gRPC status, HTTP status, and MCP error envelopes. Only invalid-argument and unauthenticated errors forward their message; everything else surfaces a registry-safe message, and internal causes never leak.
  • AI-skills layerai/v1 annotations → provider-neutral IR → MCP / OpenAI-strict / Gemini tool schemas (golden-locked). The MCP bridge dispatches tools/call back through the full interceptor chain via an in-process loopback, so AI calls inherit auth/validation.
  • Batteries — config (layered, fail-loud, masked secrets), 3-state health → gRPC Health, slog + OTLP, a PgBouncer-safe pgx pool + sqlc, and pluggable cache / MQ abstractions. The cache defaults to a process-local in-memory backend (no external service; cache.driver: redis opts in to a distributed cache, served by a small in-tree zero-dependency RESP client); MQ is NATS or Kafka. MQ delivery semantics are uniform across backends: mq.group_id empty (default) fans out, non-empty load-balances (NATS queue group / Kafka consumer group); mq.url accepts a comma-separated server list. The Kafka backend compiles only under the integration build tag — default builds return an error for mq.driver: kafka.

Quickstart

Install the dev toolchain — a Homebrew-style one-liner that corrects the Go env and installs the pinned tools (buf, protoc plugins, sqlc, …):

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/yshengliao/gortexa/main/install.sh)"

Install the CLI:

go install github.com/yshengliao/gortexa/cmd/gortexa@latest

Scaffold a project, generate a CRUD API, and run it on one h2c port (:8080):

gortexa create myapp --module github.com/me/myapp
cd myapp
gortexa gen billing/v1 Invoice
gortexa run

Or work in this repo directly with make (bootstrap installs the pinned toolchain; gen runs buf lint → breaking → generate; test runs race tests with in-process fakes):

make bootstrap
make gen
make test
make run

Then, against the running server (health is open; /v1/resources/x returns 401 — auth is shared with gRPC):

curl localhost:8080/healthz
curl -XPOST localhost:8080/mcp -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
curl localhost:8080/v1/resources/x

Developer CLI

gortexa (in cmd/gortexa) makes the framework batteries-included:

Command What
gortexa create <path> Scaffold a new project (clone the layout, rewrite the module path).
gortexa gen <domain>/<v> [Entity] Generate a CRUD API end-to-end: proto + logic stub + server wiring, then regenerate.
gortexa regen Regenerate from proto (buf lint → breaking → generate).
gortexa run Build and run the dev server.
gortexa export --format=mcp|openai|gemini Export the project's ai/v1 tool schemas as provider-ready JSON.
gortexa tools install / sync Install / re-pin the dev toolchain (tools/go.mod directives).
gortexa skills install / list Wire the AI-assist skills into Claude/Codex/Copilot/Antigravity.
gortexa doctor Check the Go toolchain and proto tools.

Layout

Path What
proto/ Proto SSOT (resource/v1, ai/v1). Edit here, then make gen.
gen/ Generated code — never hand-edit, gitignored, produced by make gen.
internal/ Framework packages (kernel, interceptor, errors, httpcompat, mcp, …).
cmd/server/ Sample server wiring everything onto one port.
cmd/gortexa/ The gortexa developer CLI (create / gen / regen / run / tools / skills / doctor).
tools/ Pinned dev toolchain as go.mod tool directives (buf, protoc plugins, sqlc, …).
.skills/ Cross-tool AI skills (proto-regen, generating-apis, scaffolding-projects, …) for Claude/Codex/Copilot/Antigravity.

Notes

  • Requires Go 1.26 (auto-downloaded via GOTOOLCHAIN). make exports the corrected module proxy env; run install.sh once if building outside make.
  • Integration tests needing real PgBouncer/Kafka are behind the integration build tag (make test-integration); the default suite needs no services.

Deploying

  • Terminate TLS in front of it. The port is cleartext h2c and the server does no TLS itself — bearer tokens transit it — so put it behind a reverse proxy, service mesh, or load balancer that terminates TLS before exposing it.
  • Authorization is the app's job. The framework authenticates (verifies the JWT) and exposes the token's Roles via auth.ClaimsFrom(ctx), but enforces no role/permission policy — add your own checks in your handlers.
  • Register real dependency checks with app.Health().Register(...) so /readyz reflects DB/cache/MQ reachability; the sample only registers a static self.

Performance

Measured on Go 1.26 with go test -benchmem -count=8 (summarized with benchstat) on a shared Intel Xeon @ 2.1 GHz. allocs/op and B/op are the machine-independent signals; ns/op is indicative (shared CI CPU). Reproduce with go test -run='^$' -bench=. -benchmem -count=8 ./internal/....

The Go 1.26 win — errors.AsType on the error hot path. The three-transport error resolver swapped the reflection-based errors.As for the new generic errors.AsType[*Error], removing one allocation per resolve. Same-toolchain A/B (go1.26.4, BenchmarkErrorResolve, n=8, on the earlier 2.8 GHz host — the durable result is the allocation reduction, which the current run above still confirms at 104 B / 2 allocs):

resolve via ns/op B/op allocs/op
errors.As (before) 242.3 112 3
errors.AsType (after) 144.8 104 2
Δ −40% −7% −33% (p=0.000)

The toolchain bump itself (Green Tea GC, faster io.ReadAll) is allocation-neutral on the other hot paths — no regressions, with the measurable framework win coming from the errors.AsType adoption above.

Framework hot paths (go1.26.4, -benchmem -count=8):

Hot path ns/op B/op allocs/op
Error resolve → gRPC status (3-transport map) ~105 104 2
Rate-limiter Allow (sharded, serial) ~197 0 0
Rate-limiter Allow (parallel) ~50 0 0
MCP tool downgrade (per tool) ~14 2 1
MCP tools/list (memoized) ~285 360 3
Resource clone (proto deep-copy) ~195 176 2
Resource get (in-memory store) ~214 176 2
Full interceptor chain (8 stages, unary) ~2,383 1,968 27

The paths that must never allocate (rate-limiter Allow) hold at 0 allocs/op. The fourth-round hardening is allocation-neutral on these paths (benchstat before/after: rate-limiter Allow stays 0 allocs/op, the full interceptor chain holds at 27 allocs/op — the added transport-boundary error normalization only runs on the error path, so the success path is unchanged). BenchmarkBridgeHandlePost separately drives a 512 KB MCP request through the full HTTP → JSON-RPC → dispatch path to exercise Go 1.26's faster io.ReadAll; at that body size the read/parse allocation (~1.6 MB) dominates, so it measures end-to-end large-body handling rather than io.ReadAll in isolation.

Provenance

Gortexa was built with AI-assisted development and hardened through four independent model review rounds — correctness, concurrency, security, and protocol conformance — with every actionable finding fixed and verified (make build / vet / test -race / lint):

Model Role
Claude Fable 5 Fourth full-codebase review, hardening fixes, and comprehensive test coverage
Claude Opus 4.8 Design, implementation, and consolidation
Gemini 3.1 Pro (Jules) Second independent review
Codex 5.5 Third independent review

License

Released under the MIT License.

Directories

Path Synopsis
cmd
gortexa command
Command gortexa is the Gortexa developer CLI.
Command gortexa is the Gortexa developer CLI.
gortexa/internal/cli
Package cli implements the gortexa developer CLI: scaffold projects, generate APIs from proto, regenerate code, and manage the dev toolchain and AI skills.
Package cli implements the gortexa developer CLI: scaffold projects, generate APIs from proto, regenerate code, and manage the dev toolchain and AI skills.
server command
Command server runs the Gortexa sample service: one h2c port serving gRPC, HTTP/JSON (grpc-gateway) and MCP for the resource.v1.ResourceService.
Command server runs the Gortexa sample service: one h2c port serving gRPC, HTTP/JSON (grpc-gateway) and MCP for the resource.v1.ResourceService.
internal
auth
Package auth implements HS256 JWT verification and signing plus context helpers for propagating verified claims.
Package auth implements HS256 JWT verification and signing plus context helpers for propagating verified claims.
cache
Package cache is a pluggable key/value cache abstraction.
Package cache is a pluggable key/value cache abstraction.
cache/resp
Package resp is a minimal, dependency-free RESP2 Redis client — just the GET/SET/DEL/PING surface the cache needs, plus a bounded connection pool.
Package resp is a minimal, dependency-free RESP2 Redis client — just the GET/SET/DEL/PING surface the cache needs, plus a bounded connection pool.
config
Package config builds Gortexa's configuration from layered sources with a fixed precedence: built-in defaults < YAML file < .env file < process environment (GORTEXA_ prefix, "__" for nesting).
Package config builds Gortexa's configuration from layered sources with a fixed precedence: built-in defaults < YAML file < .env file < process environment (GORTEXA_ prefix, "__" for nesting).
errors
Package errors is Gortexa's central error model.
Package errors is Gortexa's central error model.
health
Package health provides a concurrency-safe three-state health registry (Healthy / Degraded / Unhealthy) and a bridge to the standard gRPC health protocol.
Package health provides a concurrency-safe three-state health registry (Healthy / Degraded / Unhealthy) and a bridge to the standard gRPC health protocol.
httpcompat
Package httpcompat builds the grpc-gateway HTTP/JSON layer: a ServeMux whose error handler funnels through internal/errors (so HTTP, gRPC and MCP all map errors identically and Internal never leaks), a protojson marshaler, and an incoming header matcher that forwards Authorization to the gRPC metadata key the auth interceptor reads — so HTTP and gRPC share one auth path.
Package httpcompat builds the grpc-gateway HTTP/JSON layer: a ServeMux whose error handler funnels through internal/errors (so HTTP, gRPC and MCP all map errors identically and Internal never leaks), a protojson marshaler, and an incoming header matcher that forwards Authorization to the gRPC metadata key the auth interceptor reads — so HTTP and gRPC share one auth path.
interceptor
Package interceptor provides Gortexa's gRPC server interceptors and the fixed-order chain that wires them.
Package interceptor provides Gortexa's gRPC server interceptors and the fixed-order chain that wires them.
logic
Package logic holds Gortexa's sample business logic: an in-memory ResourceService used to exercise the framework end-to-end (gRPC, gateway, MCP).
Package logic holds Gortexa's sample business logic: an in-memory ResourceService used to exercise the framework end-to-end (gRPC, gateway, MCP).
mcp
Package mcp turns Gortexa's proto contract into AI-agent tools.
Package mcp turns Gortexa's proto contract into AI-agent tools.
mq
Package mq is a pluggable publish/subscribe abstraction with a NATS implementation (tested against an embedded server) and a Kafka implementation behind the integration build tag.
Package mq is a pluggable publish/subscribe abstraction with a NATS implementation (tested against an embedded server) and a Kafka implementation behind the integration build tag.
observability
Package observability wires Gortexa's logging, tracing and metrics.
Package observability wires Gortexa's logging, tracing and metrics.
storage
Package storage builds a PgBouncer-safe pgx connection pool and a query tracer that emits OTel DB spans.
Package storage builds a PgBouncer-safe pgx connection pool and a query tracer that emits OTel DB spans.
Package testutil provides in-process test helpers: a bufconn gRPC server wired with the full interceptor chain, golden-file comparison, and goroutine leak assertions.
Package testutil provides in-process test helpers: a bufconn gRPC server wired with the full interceptor chain, golden-file comparison, and goroutine leak assertions.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL