跳到內容

手動快速開始

安裝開發工具鏈(buf、protoc plugins、sqlc、govulncheck,版本全部 pinned):

Terminal window
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

Terminal window
export PATH="$(go env GOPATH)/bin:$PATH" # 建議加進 shell profile

裝完可以用 gortexa doctor 檢查 Go toolchain 與 proto 工具是否就緒。

Terminal window
gortexa create myapp --module github.com/me/myapp \
--repo https://github.com/yshengliao/gortexa.git --ref v0.27.0
cd myapp
# 不印出舊值地移除 create 生成的可用 secret;placeholder 會拒絕沒有 env 的啟動。
perl -0pi -e 's/(jwt_secret:\s*")[^"]*(")/${1}dev-only-insecure-secret-change-me-please${2}/' etc/config.yaml
grep -Fq 'jwt_secret: "dev-only-insecure-secret-change-me-please"' etc/config.yaml

create 會複製框架佈局、改寫 module path、丟棄 git 歷史。產出的專案自帶一個 sample resource、完整攔截器鏈、config、health 與 MCP bridge。

Terminal window
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。

Terminal window
set -euo pipefail
export 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 TERM
for _ in $(seq 1 60); do
if curl -fsS http://127.0.0.1:8080/healthz >/dev/null 2>&1; then break; fi
sleep 0.5
done
curl -fsS http://127.0.0.1:8080/healthz
test "$(curl -sS -o /dev/null -w '%{http_code}' http://127.0.0.1:8080/v1/resources/x)" = 401
curl -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 停止。

伺服器仍在上一步的同一個 shell 中執行。先確認暫時 command 尚不存在,再建立它的資料夾:

Terminal window
test ! -e cmd/devtoken
mkdir -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:

Terminal window
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" = 404
printf 'authenticated HTTP status=%s\n' "$AUTH_STATUS"
rm cmd/devtoken/main.go
rmdir cmd/devtoken
cleanup
trap - EXIT INT TERM

不要把 real secret 從 etc/config.yaml 複製、提交或打進 image。正式環境請改由 secret manager、mounted file 或 runtime environment 注入並輪替。

框架的所有 package 都可以直接 go get 單獨引用,不必建立 scaffold 專案:

Terminal window
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 治理鏈、httpcompat gateway mux、apperr 三協議錯誤模型,加上 mqcachestorageclient
  • 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。

直接開發框架本身時用 make:

Terminal window
make bootstrap # 安裝 pinned 工具鏈
make gen # buf lint → breaking → generate
make test # go test -race
make run # 啟動範例伺服器(注入本機開發用 JWT secret)
make dev # docker compose 起 Jaeger、Grafana、Prometheus
  • 核心概念:單一 port 多工、攔截器鏈、錯誤模型怎麼運作。
  • 設定:config.yaml 全欄位與環境變數覆寫。
  • 範例索引:11 個可執行的驗證範例。