/
context.go
110 lines (102 loc) · 1.89 KB
/
context.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package api
import (
"github.com/gin-gonic/gin"
"github.com/konveyor/tackle2-hub/auth"
"gorm.io/gorm"
"net/http"
"sigs.k8s.io/controller-runtime/pkg/client"
)
//
// Context custom settings.
type Context struct {
*gin.Context
// DB client.
DB *gorm.DB
// User
User string
// Scope
Scopes []auth.Scope
// k8s Client
Client client.Client
// Response
Response Response
}
//
// Response values.
type Response struct {
Status int
Body interface{}
}
//
// Status sets the values to respond to the request with.
func (r *Context) Status(status int) {
r.Response = Response{
Status: status,
Body: nil,
}
}
//
// Respond sets the values to respond to the request with.
func (r *Context) Respond(status int, body interface{}) {
r.Response = Response{
Status: status,
Body: body,
}
}
//
// WithContext is a rich context.
func WithContext(ctx *gin.Context) (n *Context) {
key := "RichContext"
object, found := ctx.Get(key)
if !found {
n = &Context{}
ctx.Set(key, n)
} else {
n = object.(*Context)
}
n.Context = ctx
return
}
//
// Transaction handler.
func Transaction(ctx *gin.Context) {
switch ctx.Request.Method {
case http.MethodPost,
http.MethodPut,
http.MethodPatch,
http.MethodDelete:
rtx := WithContext(ctx)
err := rtx.DB.Transaction(func(tx *gorm.DB) (err error) {
db := rtx.DB
rtx.DB = tx
ctx.Next()
rtx.DB = db
if len(ctx.Errors) > 0 {
err = ctx.Errors[0]
ctx.Errors = nil
}
return
})
if err != nil {
_ = ctx.Error(err)
}
}
}
//
// Render renders the response based on the Accept: header.
// Opinionated towards json.
func Render() gin.HandlerFunc {
return func(ctx *gin.Context) {
ctx.Next()
rtx := WithContext(ctx)
if rtx.Response.Body != nil {
ctx.Negotiate(
rtx.Response.Status,
gin.Negotiate{
Offered: BindMIMEs,
Data: rtx.Response.Body})
return
}
ctx.Status(rtx.Response.Status)
}
}