如何为所有 API 端点全局设置 http.ResponseWriter Content-Type 标头?

Posted

技术标签:

【中文标题】如何为所有 API 端点全局设置 http.ResponseWriter Content-Type 标头?【英文标题】:How to set http.ResponseWriter Content-Type header globally for all API endpoints? 【发布时间】:2018-12-29 13:48:18 【问题描述】:

我是 Go 新手,我现在正在用它构建一个简单的 API:

package main

import (
    "encoding/json"
    "fmt"
    "github.com/gorilla/mux"
    "github.com/gorilla/handlers"
    "log"
    "net/http"
)

func main() 
    port := ":3000"
    var router = mux.NewRouter()
    router.HandleFunc("/m/msg", handleMessage).Methods("GET")
    router.HandleFunc("/n/num", handleNumber).Methods("GET")

    headersOk := handlers.AllowedHeaders([]string"Authorization")
    originsOk := handlers.AllowedOrigins([]string"*")
    methodsOk := handlers.AllowedMethods([]string"GET", "POST", "OPTIONS")

    fmt.Printf("Server is running at http://localhost%s\n", port)
    log.Fatal(http.ListenAndServe(port, handlers.CORS(originsOk, headersOk, methodsOk)(router)))


func handleMessage(w http.ResponseWriter, r *http.Request) 
    vars := mux.Vars(r)
    message := vars["msg"]
    response := map[string]string"message": message
    w.Header().Set("Content-Type", "application/json") // this
    json.NewEncoder(w).Encode(response)


func handleNumber(w http.ResponseWriter, r *http.Request) 
    vars := mux.Vars(r)
    number := vars["num"]
    response := map[string]string"number": number
    w.Header().Set("Content-Type", "application/json") // and this
    json.NewEncoder(w).Encode(response)

我觉得在我拥有的每个 API 函数中不断重复 w.Header().Set("Content-Type", "application/json") 行并不干净。

所以我的问题是,是否可以为我拥有的所有 API 函数全局设置 http.ResponseWriter Content-Type 标头?

【问题讨论】:

github.com/gorilla/mux/blob/master/README.md#middleware 谢谢@Peter。 【参考方案1】:

你可以为复用路由器定义middleware,这里是一个例子:

func main() 
    port := ":3000"
    var router = mux.NewRouter()
    router.Use(commonMiddleware)

    router.HandleFunc("/m/msg", handleMessage).Methods("GET")
    router.HandleFunc("/n/num", handleNumber).Methods("GET")
    // rest of code goes here


func commonMiddleware(next http.Handler) http.Handler 
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) 
        w.Header().Add("Content-Type", "application/json")
        next.ServeHTTP(w, r)
    )

在documentation了解更多信息

【讨论】:

完美运行。非常感谢。 我很困惑在这里写信给ResponseWriter 是否符合犹太教规。来自current docs:“如果中间件要终止请求,则应写入 ResponseWriter,如果不终止请求,则不应写入 ResponseWriter。” 它不 write 标题。只有WriteHeader 方法可以。 啊!这就解释了。感谢您的澄清和快速回复。

以上是关于如何为所有 API 端点全局设置 http.ResponseWriter Content-Type 标头?的主要内容,如果未能解决你的问题,请参考以下文章

如何为端点上的不同请求设置单独的计数器指标?

如何为逐步连续上传用例制作 API 端点?

K6 负载测试 - 如何为整个测试运行创建顺序 ID

如何为具有 Spring Security 配置的 Spring Boot API 编写单元测试

如何为我的项目(VB.Net)中的所有水晶报表设置全局连接字符串

如何为 BlobContainerClient 设置 dfs insted blob 端点