-
Notifications
You must be signed in to change notification settings - Fork 0
schema_en.md
Attach metadata (input/output types, descriptions, tags) to routes so that AI can understand API behavior without tracing handler implementations. Supports REST, gRPC, Bot, MCP, WebSocket, and CLI protocols.
Traditional routes only tell the framework "which handler this URL maps to," requiring AI to read handler source code to understand the API. Schema-first routes attach metadata directly to routes:
Traditional: r.POST("/api/users", createUserHandler) <- AI needs to read handler source
Schema: r.Schema(Route{...}).Handle(handler) <- AI understands directly from metadata
import "github.com/maoxiaoyue/hypgo/pkg/schema" // Define request/response types type CreateUserRequest struct { Name string `json:"name"` Email string `json:"email"` } type UserResponse struct { ID int `json:"id"` Name string `json:"name"` Email string `json:"email"` } // Register a route with schema r := router.New() r.Schema(schema.Route{ Method: "POST", Path: "/api/users", Summary: "Create user", Tags: []string{"users"}, Input: CreateUserRequest{}, Output: UserResponse{}, Responses: map[int]schema.ResponseSchema{ 201: {Description: "User created"}, 400: {Description: "Invalid input"}, }, }).Handle(createUserHandler)
api := r.NewGroup("/api/v1") api.Schema(schema.Route{ Method: "GET", Path: "/products", Summary: "Get product list", Tags: []string{"products"}, Output: []ProductResponse{}, }).Handle(listProductsHandler) // Route is automatically registered as GET /api/v1/products
Schema routes and traditional routes can coexist with full backward compatibility:
r.GET("/health", healthHandler) // Traditional route -- works as usual r.Schema(schema.Route{...}).Handle(createHandler) // Schema route -- with metadata
v0.8.5+Multi-protocol support (gRPC / Bot / MCP / WebSocket / CLI) is new in v0.8.5. v0.8.1 supports REST only.
Beyond REST, Schema supports registering command contracts for other protocols:
// gRPC schema.RegisterGRPC("UserService/CreateUser", "Create user", CreateUserReq{}, UserResp{}) // Bot (Telegram, Line, Discord, WhatsApp, etc.) schema.RegisterBot("/start", "Start the bot", nil, WelcomeMsg{}) schema.RegisterBotPlatform("telegram", "/game", "Start game", GameOpts{}, GameState{}) schema.RegisterBotPlatform("discord", "!play", "Play music", PlayReq{}, PlayResp{}) // MCP (Model Context Protocol) schema.RegisterMCP("search_repos", "Search repos", SearchInput{}, SearchOutput{}) // WebSocket message types schema.RegisterWebSocket("join_room", "Join room", JoinReq{}, JoinResp{}) // CLI subcommands schema.RegisterCLI("process", "Process data", ProcessFlags{}, ProcessResult{})
All protocols share the same Schema Registry and Manifest — AI reads one manifest to understand all APIs.
type Route struct { // Universal fields (all protocols) Protocol string // "rest"(default), "grpc", "bot", "mcp", "websocket", "cli" Command string // Non-REST command identifier Platform string // Bot-specific platform: "telegram", "line", "discord", "whatsapp" Summary string // One-line description (for AI and documentation) Description string // Detailed description Tags []string // Classification tags Input interface{} // Request Go struct (for validation) Output interface{} // Response Go struct (for validation) InputName string // Auto-populated, no manual setup needed OutputName string // Auto-populated, no manual setup needed // REST-specific (backward compatible) Method string // HTTP method (GET, POST, PUT, DELETE...) Path string // Route path (supports :param and *catchall) Params []ParamSchema // Path/query parameter descriptions Headers []HeaderSchema // Required header descriptions Responses map[int]ResponseSchema // Response descriptions per status code } // RouteKey() returns the Registry lookup key // REST: "rest|POST /api/users" // gRPC: "grpc|UserService/CreateUser" // Bot: "bot|/start" // MCP: "mcp|search_repos" // IsREST() returns true if this is a REST route
| Protocol | Command Format | Example |
|---|---|---|
rest |
Method + Path (auto) |
POST /api/users |
grpc |
Service/Method |
UserService/CreateUser |
bot |
/command or event name |
/start, follow, !play
|
mcp |
tool_name |
search_repos, create_issue
|
websocket |
message_type |
join_room, send_message
|
cli |
command_name |
process, export
|
type ParamSchema struct { Name string // Parameter name In string // "path", "query", "header" Required bool // Whether required Type string // "string", "int", "bool" Desc string // Description }
type ResponseSchema struct { Description string // Response description Type interface{} // Go struct type (for Contract Testing validation) TypeName string // Auto-populated }
All routes registered via Schema() or Register*() are stored in the global Registry:
// Query REST route (backward compatible) route, ok := schema.Global().Get("POST", "/api/users") // Query by full key (any protocol) route, ok := schema.Global().GetByKey("grpc|UserService/CreateUser") route, ok := schema.Global().GetByKey("bot|/start") // Filter by protocol grpcRoutes := schema.Global().GetByProtocol("grpc") botRoutes := schema.Global().GetByProtocol("bot") // Get all registered schemas (all protocols) all := schema.Global().All() // Check registered count count := schema.Global().Len() // Reset (for testing) schema.Global().Reset()
The Registry is thread-safe, protected by sync.RWMutex.
Provides type introspection tools for use by Manifest and Contract Testing:
// Get type name schema.TypeName(UserResponse{}) // -> "UserResponse" // Get struct field information fields := schema.FieldsOf(UserResponse{}) // -> [{Name:"id", Type:"integer", Required:true}, ...] // Validate JSON against struct (including required field checks) err := schema.ValidateJSON([]byte(`{"name":"alice"}`), CreateUserRequest{}) // Generate zero-value JSON (for automated testing) data := schema.GenerateZeroJSON(CreateUserRequest{}) // -> {"name":"","email":""}
| Condition | Required |
|---|---|
Name string \json:"name"`` |
Yes |
Email string \json:"email,omitempty"`` |
No (omitempty) |
Bio *string \json:"bio"`` |
No (pointer) |
json:"-" |
Skipped (not present) |
pkg/schema/
├── schema.go Route (multi-protocol), SchemaRoute, ParamSchema type definitions
├── registry.go Global thread-safe Registry (supports RouteKey multi-protocol lookup)
├── helpers.go RegisterGRPC/Bot/MCP/WebSocket/CLI convenience functions
├── reflect.go TypeName, FieldsOf, ValidateJSON reflection utilities
└── schema_test.go Unit tests
pkg/schema <- Only depends on pkg/context (HandlerFunc type)
<- Does not depend on pkg/router (avoids circular dependency)
The SchemaRegistrar interface is defined by schema, implemented by Router and Group, avoiding circular dependencies.
設計文件
套件
- config — 設定
- context — 請求上下文
- router — 路由器
- server — 伺服器
- middleware — 中介層
- websocket — WebSocket
- hidb — 資料庫 ORM
- hidb/cassandra — Cassandra
- logger — 日誌
- json — JSON 處理
- grpc — gRPC
AI 協作工具鏈
- schema — Schema-first 路由
- manifest — 專案 Manifest
- contract — Contract Testing
- errors — Typed Error Catalog
- migrate — Migration Diff
- scaffold — 智慧 Scaffold
- airules — AI Rules
CLI 命令
- hyp 總覽
- hyp new
- hyp api
- hyp run
- hyp restart
- hyp generate
- hyp migrate
- hyp context
- hyp ai-rules
- hyp chkcomment
- hyp impact
- hyp docker
- hyp health
- hyp version
- hyp difflog
Design Docs
Packages
- config — Configuration
- context — Request Context
- router — Router
- server — Server
- middleware — Middleware
- websocket — WebSocket
- hidb — Database ORM
- hidb/cassandra - Cassandra 5.0
- logger — Logger
- json — JSON
- grpc — gRPC
AI Collaboration Toolchain
- schema — Schema-first Routing
- manifest — Project Manifest
- contract — Contract Testing
- errors — Typed Error Catalog
- migrate — Migration Diff
- scaffold — Smart Scaffold
- airules — AI Rules
CLI Commands