Skip to content

Commit ff68cb7

Browse files
committed
Implement options pattern in response handler
1 parent fa8d0b0 commit ff68cb7

File tree

3 files changed

+208
-217
lines changed

3 files changed

+208
-217
lines changed

internal/api/apilibs/response.go

Lines changed: 62 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,59 @@ import (
88
errors "github.com/rabbytesoftware/quiver/internal/core/errs"
99
)
1010

11-
type Response[T any] struct {
11+
type Response struct {
1212
Success bool `json:"success"`
13-
Payload T `json:"payload,omitempty"`
13+
Payload interface{} `json:"payload,omitempty"`
1414
Error *errors.Error `json:"error,omitempty"`
1515
Warnings []string `json:"warnings,omitempty"`
1616
Timestamp time.Time `json:"timestamp"`
1717
ResponseTime string `json:"responseTime"`
1818
}
1919

20-
type ResponseInput[T any] struct {
21-
StatusSuccess int `json:"status,omitempty"`
22-
Payload T `json:"payload,omitempty"`
23-
Error *errors.Error `json:"error,omitempty"`
24-
Warnings []error `json:"warnings,omitempty"`
20+
type responseOptions struct {
21+
Payload interface{} `json:"payload,omitempty"`
22+
Error *errors.Error `json:"error,omitempty"`
23+
Warnings []string `json:"warnings,omitempty"`
24+
Code int `json:"code,omitempty"`
25+
}
26+
27+
type ResponseOption func(*responseOptions)
28+
29+
func defaultResponseOptions() *responseOptions {
30+
return &responseOptions{
31+
Payload: nil,
32+
Error: nil,
33+
Warnings: nil,
34+
Code: int(errors.SuccessCode),
35+
}
36+
}
37+
38+
func WithError(err *errors.Error) ResponseOption {
39+
return func(o *responseOptions) {
40+
o.Error = err
41+
}
42+
}
43+
44+
func WithWarnings(warns []error) ResponseOption {
45+
return func(o *responseOptions) {
46+
o.Warnings = errorsToStrings(warns)
47+
}
48+
}
49+
50+
func WithPayload(p interface{}) ResponseOption {
51+
return func(o *responseOptions) {
52+
o.Payload = p
53+
}
54+
}
55+
56+
func WithSuccessCode(code int) ResponseOption {
57+
return func(o *responseOptions) {
58+
if code < 200 || code >= 300 {
59+
return
60+
}
61+
62+
o.Code = code
63+
}
2564
}
2665

2766
func getRequestStartTime(c *gin.Context) (time.Time, bool) {
@@ -42,28 +81,33 @@ func errorsToStrings(errs []error) []string {
4281
return out
4382
}
4483

45-
func ToResponse[T any](c *gin.Context, in ResponseInput[T]) {
84+
func ToResponse(c *gin.Context, opts ...ResponseOption) {
4685
var statusCode int
4786
startTime, _ := getRequestStartTime(c)
87+
o := defaultResponseOptions()
88+
89+
for _, opt := range opts {
90+
opt(o)
91+
}
4892

4993
switch {
50-
case in.StatusSuccess != 0 && in.Error == nil && len(in.Warnings) == 0:
51-
statusCode = in.StatusSuccess
52-
case in.Error != nil:
53-
statusCode = int(in.Error.Code)
54-
case len(in.Warnings) > 0:
94+
case o.Code != 0 && o.Error == nil && len(o.Warnings) == 0:
95+
statusCode = o.Code
96+
case o.Error != nil:
97+
statusCode = int(o.Error.Code)
98+
case len(o.Warnings) > 0:
5599
statusCode = http.StatusPartialContent
56100
default:
57101
statusCode = http.StatusOK
58102
}
59103

60-
success := statusCode >= 200 && statusCode < 300 && len(in.Warnings) == 0
104+
success := statusCode >= 200 && statusCode < 300 && len(o.Warnings) == 0
61105

62-
c.JSON(statusCode, Response[T]{
106+
c.JSON(statusCode, Response{
63107
Success: success,
64-
Payload: in.Payload,
65-
Error: in.Error,
66-
Warnings: errorsToStrings(in.Warnings),
108+
Payload: o.Payload,
109+
Error: o.Error,
110+
Warnings: o.Warnings,
67111
Timestamp: time.Now().UTC(),
68112
ResponseTime: time.Since(startTime).String(),
69113
})

0 commit comments

Comments
 (0)