使用Go语言编写的中间件可以将项目添加到响应头中。

huangapple go评论85阅读模式
英文:

Go chi middleware to add item to response header

问题

我的概念很简单,我想要将请求ID(由chi middleware.RequestID生成)添加到响应头中。

我的代码在下面添加了X-Request-Id,但没有添加ID本身。我不确定为什么,因为在中间件链中middleware.RequestID肯定是可用的。

我的路由创建:

package rest

import (
	"time"

	"github.com/go-chi/chi/v5"
	"github.com/go-chi/chi/v5/middleware"
	"goWebAPI/pkg/database"
	"goWebAPI/pkg/rest/mw"
	"goWebAPI/pkg/rest/routes"
)

func GetRouter(db *database.Database) *chi.Mux {
	r := chi.NewRouter()
	r.Use(middleware.RequestID)
	r.Use(mw.SendRequestID)
	r.Use(middleware.RealIP)
	r.Use(middleware.Logger)
	r.Use(middleware.Recoverer)
	r.Use(middleware.Timeout(60 * time.Second))
	r.Get("/", routes.IndexRoute())
	return r
}

我的自定义中间件:

package mw

import (
	"context"
	"net/http"

	"github.com/go-chi/chi/v5/middleware"
)

const requestIDHeader = "X-Request-Id"

func SendRequestID(next http.Handler) http.Handler {
	fn := func(w http.ResponseWriter, r *http.Request) {
		ctx := r.Context()
		if w.Header().Get(requestIDHeader) == "" {
			w.Header().Add(
				requestIDHeader,
				middleware.GetReqID(context.Background()),
			)
		}
		next.ServeHTTP(w, r.WithContext(ctx))
	}
	return http.HandlerFunc(fn)
}

我的索引路由:

package routes

import "net/http"

func IndexRoute() http.HandlerFunc {
	fn := func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("welcome"))
	}
	return fn
}
英文:

My concept is simple, I would like to add the request ID (generated by chi middleware.RequestID to the response header).

My code below adds X-Request-Id but does not add the ID itself. I am not sure why, since surely it is available in the context because middleware.RequestID is higher up in the middleware chain ?

My router creation:

package rest

import (
	"time"

	"github.com/go-chi/chi/v5"
	"github.com/go-chi/chi/v5/middleware"
	"goWebAPI/pkg/database"
	"goWebAPI/pkg/rest/mw"
	"goWebAPI/pkg/rest/routes"
)

func GetRouter(db *database.Database) *chi.Mux {
	r := chi.NewRouter()
	r.Use(middleware.RequestID)
	r.Use(mw.SendRequestID)
	r.Use(middleware.RealIP)
	r.Use(middleware.Logger)
	r.Use(middleware.Recoverer)
	r.Use(middleware.Timeout(60 * time.Second))
	r.Get("/", routes.IndexRoute())
	return r
}

My custom middleware:

package mw

import (
	"context"
	"net/http"

	"github.com/go-chi/chi/v5/middleware"
)

const requestIDHeader = "X-Request-Id"

func SendRequestID(next http.Handler) http.Handler {
	fn := func(w http.ResponseWriter, r *http.Request) {
		ctx := r.Context()
		if w.Header().Get(requestIDHeader) == "" {
			w.Header().Add(
				requestIDHeader,
				middleware.GetReqID(context.Background()),
			)
		}
		next.ServeHTTP(w, r.WithContext(ctx))
	}
	return http.HandlerFunc(fn)
}

My Index Route:

package routes

import "net/http"

func IndexRoute() http.HandlerFunc {
	fn:= func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("welcome"))
	}
	return fn
}

答案1

得分: 4

我相信你的问题在这里:

middleware.GetReqID(context.Background())

这个代码尝试从一个新的空上下文中获取请求ID,但你需要当前请求的请求ID,所以应该是:

middleware.GetReqID(r.Context())

(或者,既然你已经在本地的ctx中获取了请求上下文,你也可以使用它。)

这在GetReqId的文档中有说明(我加了重点):

> 如果存在,从给定的上下文中返回请求ID。如果找不到请求ID,则返回空字符串。

英文:

I believe your issue is here:

middleware.GetReqID(context.Background())

This tries to get the request ID of a new, empty context, but you need the request ID for the current request, meaning it should be:

middleware.GetReqID(r.Context())

(Or, since you're already grabbing the request context in local ctx, you could also use that.)

This is documented in GetReqId (emphasis mine):

> GetReqID returns a request ID from the given context if one is present. Returns the empty string if a request ID cannot be found.

huangapple
  • 本文由 发表于 2021年7月10日 01:22:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/68320666.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定