all repos

onasty @ 36f59cd12d0992b16f20057c23cfe0e3c338e637

a one-time notes service

onasty/internal/transport/http/reqid/reqid.go (view raw)

Smirnov Oleksandr Smirnov Oleksandr
ss2316544@gmail.com
refactor: deal with TODOs and typos (#30)..., 1 year ago
1
// reqid provides gin-gonic/gin middleware to generate a requestid for each request
2
package reqid
3
4
import (
5
	"context"
6
7
	"github.com/gin-gonic/gin"
8
	"github.com/gofrs/uuid/v5"
9
)
10
11
type requestIDKey string
12
13
const (
14
	RequestID requestIDKey = "request_id"
15
16
	headerRequestID = "X-Request-ID"
17
)
18
19
// Middleware initializes the request ID
20
func Middleware() gin.HandlerFunc {
21
	return func(c *gin.Context) {
22
		rid := c.GetHeader(headerRequestID)
23
		if rid == "" {
24
			rid = uuid.Must(uuid.NewV4()).String()
25
			c.Request.Header.Add(headerRequestID, rid)
26
		}
27
28
		// set request ID request context
29
		ctx := context.WithValue(c.Request.Context(), RequestID, rid)
30
		c.Request = c.Request.WithContext(ctx)
31
32
		// ensures that the request ID is in the response
33
		c.Header(headerRequestID, rid)
34
		c.Next()
35
	}
36
}
37
38
// Get returns the request ID
39
func Get(c *gin.Context) string {
40
	return c.GetHeader(headerRequestID)
41
}
42
43
// GetContext returns the request ID from context
44
func GetContext(ctx context.Context) string {
45
	rid, ok := ctx.Value(RequestID).(string)
46
	if !ok {
47
		return ""
48
	}
49
	return rid
50
}
51
52
// SetContext gets a parent context and returns a child context with the set provided request ID
53
func SetContext(ctx context.Context, rid string) context.Context {
54
	return context.WithValue(ctx, RequestID, rid)
55
}