MetaMessage 改變 Web 生態
MetaMessage 改變 Web 生態

MetaMessage已經支持了c、c++、c#、golang、python、rust、php、swift、kotlin、java、typescript、javascript等語言,這些語言之間的數據結構一致、語意相同、數值相等,具有統一結構化數據序列化/反序列化協議的趨勢。成為ai時代的終極協議。
下面介紹下MetaMessage載golang web 開發中的實踐:
github項目:metamessage/mm-web-go
這個項目為gin、echo、fiber、chi、net/http原生提供了支持,可以方便地使用MetaMessage進行編解碼。
Schema 發現
服務端的泛型路由(GET/POST/PUT/DELETE/PATCH)會自動註冊 OPTIONS 端點用於 Schema 發現。OPTIONS 響應會返回一個 MetaMessage 編碼的結構體實例,其中包含完整的類型、約束條件與描述元數據。
客戶端在發送實際請求前,會自動利用此機制進行請求驗證:
客戶端 服務端
│ │
├── OPTIONS /api/v1/users ──────►
│◄──── MetaMessage Schema ──────┤
│ (struct definition) │
│ │
├── POST /api/v1/users ────────►
│◄──── MetaMessage Response ────┤
服務端
非常簡單,返回的結構會自動註冊。所有框架提供完全一致的泛型路由註冊 API,handler 簽名統一為 func(ctx, *T) (any, string, error)。
net/http原生
import server "github.com/metamessage/mm-web-go/mmvanilla"
mux := http.NewServeMux()
server.Init(mux, "/api/v1")
server.GET("/users", func(r *http.Request, req *any) (any, string, error) {
return ListUsersResponse{...}, "", nil
})
server.POST("/users", func(r *http.Request, req *CreateUserRequest) (any, string, error) {
return UserResponse{...}, "", nil
})
Gin
import "github.com/gin-gonic/gin"
import server "github.com/metamessage/mm-web-go/mmgin"
r := gin.Default()
server.Init(r, "/api/v1")
// 泛型路由:自動綁定 + OPTIONS Schema 發現
server.GET("/users", func(c *gin.Context, req *any) (any, string, error) {
return ListUsersResponse{...}, "", nil
})
server.GET("/users/:id", func(c *gin.Context, req *any) (any, string, error) {
return APIResponse{...}, "", nil
})
server.POST("/users", func(c *gin.Context, req *CreateUserRequest) (any, string, error) {
return UserResponse{...}, "", nil
})
server.PUT("/users/:id", func(c *gin.Context, req *UpdateUserRequest) (any, string, error) {
return APIResponse{...}, "", nil
})
server.DELETE("/users/:id", func(c *gin.Context, req *any) (any, string, error) {
return APIResponse{...}, "", nil
})
Echo
import "github.com/labstack/echo/v4"
import server "github.com/metamessage/mm-web-go/mmecho"
e := echo.New()
server.Init(e, "/api/v1")
server.GET("/users", func(c echo.Context, req *any) (any, string, error) {
return ListUsersResponse{...}, "", nil
})
server.POST("/users", func(c echo.Context, req *CreateUserRequest) (any, string, error) {
return UserResponse{...}, "", nil
})
Fiber
import "github.com/gofiber/fiber/v2"
import server "github.com/metamessage/mm-web-go/mmfiber"
app := fiber.New()
server.Init(app, "/api/v1")
server.GET("/users", func(c *fiber.Ctx, req *any) (any, string, error) {
return ListUsersResponse{...}, "", nil
})
server.POST("/users", func(c *fiber.Ctx, req *CreateUserRequest) (any, string, error) {
return UserResponse{...}, "", nil
})
Chi
import "github.com/go-chi/chi/v5"
import server "github.com/metamessage/mm-web-go/mmchi"
r := chi.NewRouter()
server.Init(r, "/api/v1")
server.GET("/users", func(r *http.Request, req *any) (any, string, error) {
return ListUsersResponse{...}, "", nil
})
server.POST("/users", func(r *http.Request, req *CreateUserRequest) (any, string, error) {
return UserResponse{...}, "", nil
})
數據綁定
框架推薦使用post/put/patch等使用body的請求方法,攜帶二進制數據更方便。
同時對get/delete等只支持url的請求方式做了兼容,使用 ?data=<hex> 攜帶數據
Bind
將請求體綁定到結構體(自動檢測格式):
var user User
if err := mmgin.Bind(c, &user); err != nil {
// 處理錯誤
}
BindQuery
將查詢參數綁定到結構體(從 ?data=<hex> 讀取 MetaMessage 編碼數據):
var filter Filter
if err := mmgin.BindQuery(c, &filter); err != nil {
// 處理錯誤
}
客戶端
以類型安全的請求/響應執行泛型請求。會自動先發送 OPTIONS 預檢請求驗證 Schema
當然這個工作可以交給框架,不需要多寫代碼
resp, err := client.DoRequest[CreateUserRequest, UserResponse](
c, "POST", "/api/v1/users", req,
)
便捷函數
使用默認客戶端的包級別便捷函數:
client.GET[any, ListUsersResponse]("/api/v1/users", nil)
client.POST[CreateUserRequest, UserResponse]("/api/v1/users", req)
client.PUT[UpdateUserRequest, APIResponse]("/api/v1/users/1", req)
client.DELETE[any, APIResponse]("/api/v1/users/1", nil)
client.PATCH[UpdateUserRequest, APIResponse]("/api/v1/users/1", req)
- 点赞
- 收藏
- 关注作者
评论(0)