手動快速開始
安裝開發工具鏈(buf、protoc plugins、sqlc、govulncheck,版本全部 pinned):
GORTEXA_VERSION="v0.27.0" # 只在驗證過較新 release 後才更新export GORTEXA_REF="$GORTEXA_VERSION"export GOTOOLCHAIN=auto/bin/bash -c "$(curl -fsSL "https://raw.githubusercontent.com/yshengliao/gortexa/$GORTEXA_VERSION/install.sh")"go install github.com/yshengliao/gortexa/cmd/gortexa@"$GORTEXA_VERSION"在 checkout 之外執行時,腳本會把 repo clone 到 ./gortexa(用 GORTEXA_DIR 改位置,裝完可刪);只在偵測到壞掉的 container Go 設定時才寫入全域 go env,一般機器的 Go 設定不會被動到。
go install 把執行檔放在 $(go env GOPATH)/bin,多數 shell 的 PATH 預設不含這個目錄——沒加的話下一步會直接 command not found: gortexa:
export PATH="$(go env GOPATH)/bin:$PATH" # 建議加進 shell profile裝完可以用 gortexa doctor 檢查 Go toolchain 與 proto 工具是否就緒。
gortexa create myapp --module github.com/me/myapp \ --repo https://github.com/yshengliao/gortexa.git --ref v0.27.0cd myapp# 不印出舊值地移除 create 生成的可用 secret;placeholder 會拒絕沒有 env 的啟動。perl -0pi -e 's/(jwt_secret:\s*")[^"]*(")/${1}dev-only-insecure-secret-change-me-please${2}/' etc/config.yamlgrep -Fq 'jwt_secret: "dev-only-insecure-secret-change-me-please"' etc/config.yamlcreate 會複製框架佈局、改寫 module path、丟棄 git 歷史。產出的專案自帶一個 sample resource、完整攔截器鏈、config、health 與 MCP bridge。
產生第一個 API
Section titled “產生第一個 API”gortexa gen billing/v1 Invoice這個指令產生 proto contract(含 validation 與 AI annotations)、in-memory logic stub 與 server wiring,並跑完 buf lint → breaking → generate。之後改 proto 就跑 gortexa regen。
gen/ 下全是產生碼:不手動編輯,只由 make gen 產生(照框架慣例進版控,複製來的 CI 有 drift 防護閘)。
以下是單一 shell 的 smoke test:它用短期 runtime secret、保留 gortexa run 的相同 server entrypoint、等待服務就緒,並註冊 binary 與 log 的 cleanup。server 會暫留給下一段 token 流程;請不要在這些命令之間更換 shell。
set -euo pipefailexport GORTEXA_AUTH__JWT_SECRET="$(openssl rand -hex 32)"go build -o ./.gortexa-prototype-server ./cmd/server./.gortexa-prototype-server >./gortexa-prototype.log 2>&1 &SERVER_PID=$!cleanup() { kill -TERM "$SERVER_PID" 2>/dev/null || true; wait "$SERVER_PID" 2>/dev/null || true; rm -f ./.gortexa-prototype-server ./gortexa-prototype.log; }trap cleanup EXIT INT TERMfor _ in $(seq 1 60); do if curl -fsS http://127.0.0.1:8080/healthz >/dev/null 2>&1; then break; fi sleep 0.5donecurl -fsS http://127.0.0.1:8080/healthztest "$(curl -sS -o /dev/null -w '%{http_code}' http://127.0.0.1:8080/v1/resources/x)" = 401curl -fsS -X POST http://127.0.0.1:8080/mcp \ -H 'Content-Type: application/json' \ -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'HTTP gateway 的最後一發回 401 是預期行為;它與 gRPC、MCP 共用 authentication。這個 smoke test 不代替 live gRPC E2E 或 authorization 測試。若只需要 smoke test、不會繼續下一段,現在執行 cleanup; trap - EXIT INT TERM 即可停止 server 並清除暫存檔。若要一般互動式開發,可在同一個已 export secret 的 shell 直接執行 gortexa run,再以 Ctrl-C 停止。
取得開發用 token
Section titled “取得開發用 token”伺服器仍在上一步的同一個 shell 中執行。先確認暫時 command 尚不存在,再建立它的資料夾:
test ! -e cmd/devtokenmkdir -p cmd/devtoken建立一個暫時 command(它不含 secret),把下列程式存為 cmd/devtoken/main.go;若 module 不是 github.com/me/myapp,替換 import:
package main
import ( "fmt" "os" "time"
"github.com/me/myapp/auth")
func main() { secret := os.Getenv("GORTEXA_AUTH__JWT_SECRET") v, err := auth.NewVerifier([]byte(secret), "gortexa") if err != nil { panic(err) } tok, err := v.Sign("dev", []string{"admin"}, time.Hour) if err != nil { panic(err) } fmt.Println(tok)}執行它、驗證 authenticated request,然後移除暫時 command 並停止 server:
TOKEN="$(go run ./cmd/devtoken)"AUTH_STATUS="$(curl -sS -o /dev/null -w '%{http_code}' http://127.0.0.1:8080/v1/resources/x -H "Authorization: Bearer $TOKEN")"test "$AUTH_STATUS" = 200 || test "$AUTH_STATUS" = 404printf 'authenticated HTTP status=%s\n' "$AUTH_STATUS"rm cmd/devtoken/main.gormdir cmd/devtokencleanuptrap - EXIT INT TERM不要把 real secret 從 etc/config.yaml 複製、提交或打進 image。正式環境請改由 secret manager、mounted file 或 runtime environment 注入並輪替。
以模組使用(不走 scaffold)
Section titled “以模組使用(不走 scaffold)”框架的所有 package 都可以直接 go get 單獨引用,不必建立 scaffold 專案:
go get github.com/yshengliao/gortexa@latest最小 app(一個 h2c port、gRPC health、/healthz、/readyz)完全不需要 codegen:
package main
import ( "context" "log" "os/signal" "syscall"
"github.com/yshengliao/gortexa/health" "github.com/yshengliao/gortexa/kernel")
func main() { ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM) defer stop()
app, err := kernel.New() // 預設:h2c :8080、graceful shutdown if err != nil { log.Fatal(err) } app.Health().Register("self", func(context.Context) health.State { return health.Healthy })
if err := app.Run(ctx); err != nil { log.Fatal(err) }}由此往上疊,AI 與非 AI 路徑都是一等公民:
- 非 AI 服務:
config分層設定、interceptor治理鏈、httpcompatgateway mux、apperr三協議錯誤模型,加上mq/cache/storage/client。 - AI 服務:proto 標上
gortexa/ai/v1/annotations.proto(Go bindings 隨模組出貨於gen/gortexa/ai/v1),以mcp.NewBridge把標注的 RPC 變成走同一條攔截器鏈的 MCP tools。
每個公開組件的用途、import 路徑與最小範例,見組件用法。
注意:gortexa create 產出的專案已內含框架原始碼(改寫成自己的 module path),不可再 go get 框架——兩份 copy 都會註冊 gortexa/ai/v1/annotations.proto,binary 會在 init 時 panic。
在框架 checkout 內開發
Section titled “在框架 checkout 內開發”直接開發框架本身時用 make:
make bootstrap # 安裝 pinned 工具鏈make gen # buf lint → breaking → generatemake test # go test -racemake run # 啟動範例伺服器(注入本機開發用 JWT secret)make dev # docker compose 起 Jaeger、Grafana、Prometheus