-
Notifications
You must be signed in to change notification settings - Fork 0
/
user.go
148 lines (117 loc) · 4.37 KB
/
user.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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
package webhttp
import (
"context"
"net/http"
"net/url"
"github.com/go-chi/chi"
"github.com/pavelmemory/faceit-users/internal/logging"
"github.com/pavelmemory/faceit-users/internal/user"
)
//go:generate mockgen -source=user.go -destination mock.go -package webhttp UserService
// UserService provides set of operations available to operate on the user entity.
type UserService interface {
// Create creates a new user entity and returns its unique identifier.
Create(ctx context.Context, user user.Entity) (string, error)
// Get returns user entity by its unique identifier.
Get(ctx context.Context, id string) (user.Entity, error)
// Update updates user entity found by unique identifier.
Update(ctx context.Context, id string, user user.Entity) error
// Delete removes user entity by its unique identifier.
Delete(ctx context.Context, id string) error
}
// NewUsersHandler returns HTTP handler initialized with provided service abstraction.
func NewUsersHandler(userService UserService) *UserHandler {
return &UserHandler{userService: userService}
}
// UserHandler handles request for the user entity(-ies).
type UserHandler struct {
userService UserService
mapper Mapper
}
// Register creates a binding between method handlers and endpoints.
func (uh *UserHandler) Register(router chi.Router) {
router = router.With(LogRequest())
router.With(ProducesJSON, AcceptsJSON).Method(http.MethodPost, uh.urlPrefix(), http.HandlerFunc(uh.Create))
router.With(ProducesJSON).Method(http.MethodGet, uh.urlPrefix()+"/{id}", http.HandlerFunc(uh.Get))
router.With(AcceptsJSON).Method(http.MethodPut, uh.urlPrefix()+"/{id}", http.HandlerFunc(uh.Update))
router.Method(http.MethodDelete, uh.urlPrefix()+"/{id}", http.HandlerFunc(uh.Delete))
}
func (uh *UserHandler) Create(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
logger := uh.logger(ctx, "Create")
logger.Debug("start")
defer logger.Debug("end")
var req CreateUserReq
if err := Decode(r.Body, &req); err != nil {
logger.WithError(err).Error("decode payload")
ErrorResponse{Cause: err, StatusCode: http.StatusBadRequest}.Write(logger, w)
return
}
id, err := uh.userService.Create(ctx, uh.mapper.createUserReq2Entity(req))
if err != nil {
logger.WithError(err).Error("creation of the Booking")
WriteError(w, logger, err)
return
}
w.Header().Set("location", uh.urlPrefix()+"/"+url.PathEscape(id))
w.WriteHeader(http.StatusCreated)
}
func (uh *UserHandler) Get(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
logger := uh.logger(ctx, "Get")
logger.Debug("start")
defer logger.Debug("end")
id := uh.pathParam(r, "id")
u, err := uh.userService.Get(ctx, id)
if err != nil {
logger.WithError(err).WithString("id", id).Error("get user by id")
WriteError(w, logger, err)
return
}
if err := Encode(w, uh.mapper.entity2GetUserResp(u)); err != nil {
logger.WithError(err).Error("encode entity")
ErrorResponse{Cause: err, StatusCode: http.StatusInternalServerError}.Write(logger, w)
return
}
}
func (uh *UserHandler) Update(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
logger := uh.logger(ctx, "Update")
logger.Debug("start")
defer logger.Debug("end")
id := uh.pathParam(r, "id")
var req UpdateUserReq
if err := Decode(r.Body, &req); err != nil {
logger.WithError(err).Error("decode payload")
ErrorResponse{Cause: err, StatusCode: http.StatusBadRequest}.Write(logger, w)
return
}
if err := uh.userService.Update(ctx, id, uh.mapper.updateUserReq2Entity(req)); err != nil {
logger.WithError(err).WithString("id", id).Error("update user")
WriteError(w, logger, err)
return
}
w.WriteHeader(http.StatusNoContent)
}
func (uh *UserHandler) Delete(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
logger := uh.logger(ctx, "Delete")
logger.Debug("start")
defer logger.Debug("end")
id := uh.pathParam(r, "id")
if err := uh.userService.Delete(ctx, id); err != nil {
logger.WithError(err).WithString("id", id).Error("delete user")
WriteError(w, logger, err)
return
}
w.WriteHeader(http.StatusNoContent)
}
func (uh *UserHandler) urlPrefix() string {
return "/users"
}
func (uh *UserHandler) pathParam(r *http.Request, name string) string {
return chi.URLParam(r, name)
}
func (uh *UserHandler) logger(ctx context.Context, method string) logging.Logger {
return logging.FromContext(ctx).WithString("component", "UserHandler").WithString("method", method)
}