golang自动生成HTTP输入输出处理样板代码插件库VarHandler的使用
Golang自动生成HTTP输入输出处理样板代码插件库VarHandler的使用
VarHandler是一个用于简化Golang HTTP开发过程的工具,它可以自动生成HTTP输入输出处理的样板代码,同时保持HTTP兼容性。
核心功能
VarHandler能够自动生成以下HTTP处理步骤:
- 从HTTP请求获取参数并验证
- 处理验证错误
- 调用业务函数
- 处理业务函数返回的错误
- 生成HTTP响应
响应类型
业务函数可以有以下几种返回形式:
func F(x X, y Y) (err error) // 默认成功状态码200
// 未知错误返回500
func F(x X, y Y) (status int, err error) // 设置返回状态码
func F(x X, y Y) (response interface{}, err error) // 特定响应
func F(x X, y Y) (response interface{}, status int, err error) // 设置状态码和响应
参数处理
函数可以接受一个或多个参数,这些参数需要定义对应的HTTP实例化器:
HTTPX(r *http.Request) (x X, err error)
错误处理
如果实例化过程中发生错误:
HandleHttpErrorWithDefaultStatus(w, r, http.StatusBadRequest, err) // 会被调用
如果业务函数返回错误:
HandleHttpErrorWithDefaultStatus(w, r, http.StatusInternalServerError, err) // 会被调用
完整示例
传统方式
myHttpHandler(w http.ResponseWriter, r *http.Request) {
var x X
err := json.NewDecoder(r.Body).Decode(x)
if err != nil {
// 错误处理
return
}
err := validate(x)
if err != nil {
// 错误处理
return
}
// 重复处理y和z
// 从zz包获取zz
response, status, err := F(x, y, z, zz)
if err != nil {
// 返回500错误
}
w.WriteHeader(status)
json.NewEncoder(w).Encode(response)
}
使用VarHandler的方式
//go:generate varhandler -func F
package server
import "github.com/azr/generators/varhandler/examples/z"
func F(x X, y Y, z *Z, zz z.Z) (resp interface{}, status int, err error) {...}
// HTTP实例化器:
func HTTPX(r *http.Request) (x X, err error) { err = json.NewDecoder(r.Body).Decode(&x) }
func HTTPY(r *http.Request) (Y, error) {...}
func HTTPZ(r *http.Request) (*Z, error) {...}
func z.HTTPZ(r *http.Request) (z.Z, error) {...}
VarHandler会生成以下代码:
- 调用HTTPX、HTTPY、HTTPX和z.HTTPZ及其错误检查
- 调用F(x, y, z, zz)
- 根据F的返回参数生成HTTP响应代码
生成的代码示例
func FHandler(w http.ResponseWriter, r *http.Request) {
var err error
x, err := HTTPX(r)
if err != nil {
HandleHttpErrorWithDefaultStatus(w, r, http.StatusBadRequest, err)
return
}
y, err := HTTPY(r)
if err != nil {
HandleHttpErrorWithDefaultStatus(w, r, http.StatusBadRequest, err)
return
}
z, err := HTTPZ(r)
if err != nil {
HandleHttpErrorWithDefaultStatus(w, r, http.StatusBadRequest, err)
return
}
zz, err := z.HTTPZ(r)
if err != nil {
HandleHttpErrorWithDefaultStatus(w, r, http.StatusBadRequest, err)
return
}
resp, status, err := F(x, y, z, zz)
if err != nil {
HandleHttpErrorWithDefaultStatus(w, r, http.StatusInternalServerError, err)
return
}
if status != 0 { // 如果F返回了状态码
w.WriteHeader(status)
}
if resp != nil { // 如果F返回了响应对象
HandleHttpResponse(w, r, resp)
}
}
// 辅助函数
func HandleHttpErrorWithDefaultStatus(w http.ResponseWriter, r *http.Request, status int, err error) {
type HttpError interface {
HttpError() (error string, code int)
}
type SelfHttpError interface {
HttpError(w http.ResponseWriter)
}
switch t := err.(type) {
default:
w.WriteHeader(status)
case HttpError:
err, code := t.HttpError()
http.Error(w, err, code)
case http.Handler:
t.ServeHTTP(w, r)
case SelfHttpError:
t.HttpError(w)
}
}
func HandleHttpResponse(w http.ResponseWriter, r *http.Request, resp interface{}) {
type Byter interface {
Bytes() []byte
}
type Stringer interface {
String() string
}
switch t := resp.(type) {
default:
// 未知类型
case http.Handler:
t.ServeHTTP(w, r) // 响应对象知道如何处理自己
case Byter:
w.Write(t.Bytes())
case Stringer:
w.Write([]byte(t.String()))
case []byte:
w.Write(t)
}
}
更多关于golang自动生成HTTP输入输出处理样板代码插件库VarHandler的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang自动生成HTTP输入输出处理样板代码插件库VarHandler的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Golang HTTP 处理样板代码生成工具 VarHandler 使用指南
VarHandler 是一个用于自动生成 Golang HTTP 输入输出处理样板代码的工具,它可以显著减少编写 HTTP API 时的重复代码工作。
安装 VarHandler
首先安装 VarHandler 工具:
go install github.com/stoewer/go-varhandler@latest
基本使用
1. 定义处理函数
首先定义一个普通的 Go 函数,VarHandler 会根据这个函数的签名自动生成 HTTP 处理器:
//go:generate varhandler -func GetUser
func GetUser(id int64) (*User, error) {
// 业务逻辑
if id <= 0 {
return nil, errors.New("invalid user id")
}
return &User{
ID: id,
Name: "John Doe",
}, nil
}
2. 生成处理器代码
在包含上述代码的文件中运行:
go generate
这将生成一个 GetUserHandler
函数,可以直接用于 HTTP 路由。
3. 使用生成的处理器
package main
import (
"net/http"
)
func main() {
http.HandleFunc("/user", GetUserHandler)
http.ListenAndServe(":8080", nil)
}
功能特性
参数绑定
VarHandler 支持从以下位置自动绑定参数:
- URL 路径参数
- 查询字符串
- JSON 请求体
- 表单数据
- HTTP 头
//go:generate varhandler -func CreateUser
func CreateUser(req *http.Request, user *User) (*User, error) {
// 业务逻辑
return user, nil
}
响应处理
VarHandler 自动处理响应:
- 如果返回 error 不为 nil,生成 400 或 500 错误响应
- 如果返回值为非 nil,生成 200 成功响应
- 支持自定义状态码
//go:generate varhandler -func UpdateUser -status 204
func UpdateUser(id int64, user *User) error {
// 业务逻辑
return nil
}
自定义选项
VarHandler 提供多种选项来自定义行为:
//go:generate varhandler -func SearchUsers -query -response 200:[]User -response 404:ErrorResponse
func SearchUsers(query string, limit int) ([]User, error) {
// 业务逻辑
return []User{}, nil
}
高级用法
中间件支持
生成的处理器兼容标准 http.Handler 接口,可以轻松添加中间件:
func loggingMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log.Println(r.Method, r.URL.Path)
next.ServeHTTP(w, r)
})
}
func main() {
handler := loggingMiddleware(http.HandlerFunc(GetUserHandler))
http.Handle("/user", handler)
http.ListenAndServe(":8080", nil)
}
自定义错误处理
//go:generate varhandler -func GetUser -error ErrorResponse
func GetUser(id int64) (*User, error) {
if id <= 0 {
return nil, &ErrorResponse{
Code: 400,
Message: "Invalid user ID",
}
}
return &User{ID: id, Name: "John Doe"}, nil
}
实际示例
完整的 API 示例
package main
import (
"errors"
"net/http"
)
type User struct {
ID int64 `json:"id"`
Name string `json:"name"`
}
type ErrorResponse struct {
Code int `json:"code"`
Message string `json:"message"`
}
//go:generate varhandler -func GetUser -error ErrorResponse
func GetUser(id int64) (*User, error) {
if id <= 0 {
return nil, &ErrorResponse{
Code: 400,
Message: "Invalid user ID",
}
}
return &User{ID: id, Name: "John Doe"}, nil
}
//go:generate varhandler -func CreateUser -status 201
func CreateUser(user *User) (*User, error) {
if user.Name == "" {
return nil, errors.New("name is required")
}
user.ID = 1 // 模拟数据库ID分配
return user, nil
}
func main() {
http.HandleFunc("/users", func(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodGet:
GetUserHandler(w, r)
case http.MethodPost:
CreateUserHandler(w, r)
default:
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
}
})
http.ListenAndServe(":8080", nil)
}
总结
VarHandler 的主要优点:
- 减少样板代码,专注于业务逻辑
- 自动处理参数绑定和响应编码
- 支持多种输入输出格式
- 与标准库无缝集成
- 通过 go generate 轻松生成代码
通过使用 VarHandler,你可以显著提高开发 HTTP API 的效率,同时保持代码的整洁和一致性。