当前位置: 首页 > 工具软件 > gohttp > 使用案例 >

Go 语言如何自动解码 HTTP 请求参数到自定义的结构体

程谦
2023-12-01

在 Go 中,我们可以直接使用 Go 自带的 net/http 包对 HTTP 请求参数进行解析。比如看下面一个简单的用例:

// GET /v1/users?page=1&per_page=20&is_member=true
func ListUsers(rw http.ResponseWriter, r *http.Request) {
    page, err := strconv.ParseInt(r.FormValue("page"), 10, 64)
    if err != nil {
        // 处理参数错误: page.
        return
    }
    perPage, err := strconv.ParseInt(r.FormValue("per_page"), 10, 64)
    if err != nil {
        // 处理参数错误: per_page.
        return
    }
    isMember, err := strconv.ParseBool(r.FormValue("is_member"))
    if err != nil {
        // 处理参数错误: is_member.
        return
    }

    // 读取数据库并返回给客户端
}

对于这种请求,如果 URL/Query 里面带了超过 3 个参数,那么一个一个去读取/解析,再处理错误,代码就会变得很冗余。代码库也会变得不好维护,又臭又长。不仅能搞死自己,还会搞死后面接盘的小宝贝!所以说,最好就是能把一个接口的请求参数统一存放在一个结构体中。这样不仅能减少接口代码中的局部变量,也能使代码变得易读,方便维护。

比如把上面的参数可以统一定义在一个结构体中,如下:

type ListUsersInput struct {
    Page     int
    PerPage  int
    IsMember bool
}

// GET /v1/users?page=1&per_page=20&is_member=true
func ListUsers(rw http.ResponseWriter, r *http.Request) {
    input := &ListUsersInput{}
    input.Page = // ...
}

但是问题也就来了,虽然参数全存放在一个结构体了,参数不还是得一个一个去解析吗?这样还是得写一堆解析代码,也能把人活活累死。有没有一个库能一行代码搞定参数解析?

答案是:当然能啦!

这里推荐一个自动解析 HTTP 请求到 Go 结构体中的库:ggicci/httpin

使用 ggicci/httpin 库来解析 HTTP 请求参数

废话不多说,咱先看看用 httpin 怎么来实现上面的解析参数代码:

// 1. 定义一个结构体存放所有需要解析参数,并在相应字段后面用结构体标签定义参数从哪里解析
type ListUsersInput struct {
    Page     int  `in:"form=page"`
    PerPage  int  `in:"form=per_page"`
    IsMember bool `in:"form=is_member"`
}

// 2. 把这个结构体和你的接口 handler 绑定
func init() {
    http.Handle("/users", alice.New(
        httpin.NewInput(ListUsersInput{}),
    ).ThenFunc(ListUsers))
}

// 3. 在接口 handler 里面,直接读取参数,一行解析代码都不用写,httpin 帮你解析完了
func ListUsers(rw http.ResponseWriter, r *http.Request) {
    input := r.Context().Value(httpin.Input).(*ListUsersInput)
}

这样来看,是不是超级简单,干脆

广告植入:不要 998,不要 188,只要给个星星(不要脸求 star ),httpin 免费使用100年!

httpin 不仅能从 URL 提取参数,还能从 HTTP 请求的很多其它地方提取参数,反正有以下这些:

  • Query string (URL parameters), e.g. ?name=john&is_member=true
  • Headers, e.g. Authorization: xxx
  • Form data, e.g. login=john&password=*****
  • JSON/XML body, e.g. POST {“name”: “john”, “is_member”: true}
  • Path variables, e.g. /users/{username}
  • File uploads

httpin 是个不错的库,真的良心:

好啦,谢谢大家阅读!祝大家生活愉快。

 类似资料: