为了账号安全,请及时绑定邮箱和手机立即绑定

Golang http 服务器根据内容类型返回 html 或 json

Golang http 服务器根据内容类型返回 html 或 json

Go
智慧大石 2023-06-26 17:04:30
我正在尝试使用 gorilla mux 在 Golang 中编写简单的 RESTful 应用程序。我编写了一些处理程序,如下所示:func getUser(w http.ResponseWriter, r *http.Request) {    if r.Header.Get("Content-type") == "application/json" {        w.Header().Set("Content-Type", "application/json")        u, err := _getUser(r)        if err != nil {            http.NotFound(w, r)            return        }        json.NewEncoder(w).Encode(u) //asked for json, return json    } else {        w.Header().Set("Content-Type", "text/html")        u, err := _getUser(r)        if err != nil {            http.NotFound(w, r)            return        }        renderTemplate(w, "view", u) // asked for html, return html    }}func _getUser(r *http.Request) (*User, error) {    params := mux.Vars(r)    for _, u := range users {        if u.ID == params["id"] {            return &u, nil        }    }    return nil, errors.New("")}func main() {    router := mux.NewRouter()    router.HandleFunc("/v1/users/{id}", getUser).Methods("GET")}我在这里遇到的问题是我有很多重复。每个 CRUD 方法都必须检查内容类型并返回 json 或 html。我想过写一个闭包func htmlOrJSON(fn func(http.ResponseWriter, *http.Request) (interface {}, error), templateName string) http.HandlerFunc {    return func(w http.ResponseWriter, r *http.Request) {        if r.Header.Get("Content-type") == "application/json" {            w.Header().Set("Content-Type", "application/json")            result, err := fn(w, r)            if err != nil {                http.NotFound(w, r)                return            }            json.NewEncoder(w).Encode(result)        } else {            w.Header().Set("Content-Type", "text/html")            result, err := fn(w, r)            if err != nil {                http.NotFound(w, r)                return            }            renderTemplate(w, templateName, result)        }    }}// and use as:router.HandleFunc("/v1/users/{id}", htmlOrJSON(getUser, "view")).Methods("GET")删除重复但看起来也不太好。谁能帮我使这段代码更清晰吗?
查看完整描述

1 回答

?
慕容3067478

TA贡献1773条经验 获得超3个赞

虽然这是一个代码审查问题并且应该在 CodeReview 社区中,但我会尝试回答它。


编写一个处理 HTML 和 JSON 渲染的通用函数。即使您重复某些代码,错误处理 IMO 也应该在每个处理程序上发生。它在那里更有意义,并使代码更具可读性和明确性。您很快就会发现还有其他错误需要特殊处理。


从逻辑上来说,大多数API都接受查询参数http://api.com/user/1?fomtat=json。这更有意义,因为当客户端接受多种内容类型时,您就会陷入困境。


const JSON = "application/json"


func getUser(w http.ResponseWriter, r *http.Request) {

    u, err := _getUser(r)

    if err != nil {

        http.NotFound(w, r)

        return

    }

    responseBody(u, r.Header.Get("Content-type"), &w)

}


func responseBody(u User, contentType string, w io.writer) {

    switch contentType {

    case JSON:

        w.Header().Set("Content-Type", JSON)

        json.NewEncoder(w).Encode(u) //asked for json, return json

    default:

        w.Header().Set("Content-Type", "text/html")

        renderTemplate(w, "view", u) // asked for html, return html

    }

}


查看完整回答
反对 回复 2023-06-26
  • 1 回答
  • 0 关注
  • 129 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信