Skip to content

Commit 8605920

Browse files
committed
Get rid of github.com/go-chi/render use
1 parent 61dbf6b commit 8605920

File tree

8 files changed

+70
-68
lines changed

8 files changed

+70
-68
lines changed

backend/app/rest/api/admin.go

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import (
77
"time"
88

99
"github.com/go-chi/chi/v5"
10-
"github.com/go-chi/render"
1110
"github.com/go-pkgz/auth/v2"
1211
cache "github.com/go-pkgz/lcw/v2"
1312
log "github.com/go-pkgz/lgr"
@@ -54,8 +53,7 @@ func (a *admin) deleteCommentCtrl(w http.ResponseWriter, r *http.Request) {
5453
return
5554
}
5655
a.cache.Flush(cache.Flusher(locator.SiteID).Scopes(locator.SiteID, locator.URL, lastCommentsScope))
57-
render.Status(r, http.StatusOK)
58-
render.JSON(w, r, R.JSON{"id": id, "locator": locator})
56+
rest.WriteJSON(w, http.StatusOK, R.JSON{"id": id, "locator": locator})
5957
}
6058

6159
// DELETE /user/{userid}?site=side-id - delete all user comments for requested userid
@@ -69,8 +67,7 @@ func (a *admin) deleteUserCtrl(w http.ResponseWriter, r *http.Request) {
6967
return
7068
}
7169
a.cache.Flush(cache.Flusher(siteID).Scopes(userID, siteID, lastCommentsScope))
72-
render.Status(r, http.StatusOK)
73-
render.JSON(w, r, R.JSON{"user_id": userID, "site_id": siteID})
70+
rest.WriteJSON(w, http.StatusOK, R.JSON{"user_id": userID, "site_id": siteID})
7471
}
7572

7673
// GET /user/{userid}?site=side-id - get user info for requested userid
@@ -84,8 +81,7 @@ func (a *admin) getUserInfoCtrl(w http.ResponseWriter, r *http.Request) {
8481
rest.SendErrorJSON(w, r, http.StatusBadRequest, err, "can't get user info", rest.ErrInternal)
8582
return
8683
}
87-
render.Status(r, http.StatusOK)
88-
render.JSON(w, r, ucomments[0].User)
84+
rest.WriteJSON(w, http.StatusOK, ucomments[0].User)
8985
}
9086

9187
// GET /deleteme?token=jwt - delete all user comments and details by user's request. Gets info about deleted used from provided token
@@ -135,8 +131,7 @@ func (a *admin) deleteMeRequestCtrl(w http.ResponseWriter, r *http.Request) {
135131
}
136132

137133
a.cache.Flush(cache.Flusher(audience).Scopes(audience, claims.User.ID, lastCommentsScope))
138-
render.Status(r, http.StatusOK)
139-
render.JSON(w, r, R.JSON{"user_id": claims.User.ID, "site_id": claims.Audience})
134+
rest.WriteJSON(w, http.StatusOK, R.JSON{"user_id": claims.User.ID, "site_id": claims.Audience})
140135
}
141136

142137
// PUT /user/{userid}?site=side-id&block=1&ttl=7d - block or unblock user
@@ -164,7 +159,7 @@ func (a *admin) setBlockCtrl(w http.ResponseWriter, r *http.Request) {
164159
}
165160
}
166161
a.cache.Flush(cache.Flusher(siteID).Scopes(userID, siteID, lastCommentsScope))
167-
render.JSON(w, r, R.JSON{"user_id": userID, "site_id": siteID, "block": blockStatus})
162+
rest.WriteJSON(w, http.StatusOK, R.JSON{"user_id": userID, "site_id": siteID, "block": blockStatus})
168163
}
169164

170165
// GET /blocked?site=siteID - list blocked users
@@ -175,7 +170,7 @@ func (a *admin) blockedUsersCtrl(w http.ResponseWriter, r *http.Request) {
175170
rest.SendErrorJSON(w, r, http.StatusBadRequest, err, "can't get blocked users", rest.ErrSiteNotFound)
176171
return
177172
}
178-
render.JSON(w, r, users)
173+
rest.WriteJSON(w, http.StatusOK, users)
179174
}
180175

181176
// PUT /readonly?site=siteID&url=post-url&ro=1 - set or reset read-only status for the post
@@ -202,7 +197,7 @@ func (a *admin) setReadOnlyCtrl(w http.ResponseWriter, r *http.Request) {
202197
return
203198
}
204199
a.cache.Flush(cache.Flusher(locator.SiteID).Scopes(locator.URL, locator.SiteID))
205-
render.JSON(w, r, R.JSON{"locator": locator, "read-only": roStatus})
200+
rest.WriteJSON(w, http.StatusOK, R.JSON{"locator": locator, "read-only": roStatus})
206201
}
207202

208203
// PUT /title/{id}?site=siteID&url=post-url - set comment PostTitle to page's title
@@ -218,8 +213,7 @@ func (a *admin) setTitleCtrl(w http.ResponseWriter, r *http.Request) {
218213
log.Printf("[INFO] set comment's title %s to %q", id, c.PostTitle)
219214

220215
a.cache.Flush(cache.Flusher(locator.SiteID).Scopes(locator.URL, lastCommentsScope))
221-
render.Status(r, http.StatusOK)
222-
render.JSON(w, r, R.JSON{"id": id, "locator": locator})
216+
rest.WriteJSON(w, http.StatusOK, R.JSON{"id": id, "locator": locator})
223217
}
224218

225219
// PUT /verify?site=siteID&url=post-url&ro=1 - set or reset read-only status for the post
@@ -233,7 +227,7 @@ func (a *admin) setVerifyCtrl(w http.ResponseWriter, r *http.Request) {
233227
return
234228
}
235229
a.cache.Flush(cache.Flusher(siteID).Scopes(siteID, userID))
236-
render.JSON(w, r, R.JSON{"user": userID, "verified": verifyStatus})
230+
rest.WriteJSON(w, http.StatusOK, R.JSON{"user": userID, "verified": verifyStatus})
237231
}
238232

239233
// PUT /pin/{id}?site=siteID&url=post-url&pin=1
@@ -248,5 +242,5 @@ func (a *admin) setPinCtrl(w http.ResponseWriter, r *http.Request) {
248242
return
249243
}
250244
a.cache.Flush(cache.Flusher(locator.SiteID).Scopes(locator.URL))
251-
render.JSON(w, r, R.JSON{"id": commentID, "locator": locator, "pin": pinStatus})
245+
rest.WriteJSON(w, http.StatusOK, R.JSON{"id": commentID, "locator": locator, "pin": pinStatus})
252246
}

backend/app/rest/api/migrator.go

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import (
1010
"sync"
1111
"time"
1212

13-
"github.com/go-chi/render"
1413
cache "github.com/go-pkgz/lcw/v2"
1514
log "github.com/go-pkgz/lgr"
1615
R "github.com/go-pkgz/rest"
@@ -58,8 +57,7 @@ func (m *Migrator) importCtrl(w http.ResponseWriter, r *http.Request) {
5857

5958
go m.runImport(siteID, r.URL.Query().Get("provider"), tmpfile) // import runs in background and sets busy flag for site
6059

61-
render.Status(r, http.StatusAccepted)
62-
render.JSON(w, r, R.JSON{"status": "import request accepted"})
60+
rest.WriteJSON(w, http.StatusAccepted, R.JSON{"status": "import request accepted"})
6361
}
6462

6563
// POST /import/form?secret=key&site=site-id&provider=disqus|remark|wordpress
@@ -93,8 +91,7 @@ func (m *Migrator) importFormCtrl(w http.ResponseWriter, r *http.Request) {
9391

9492
go m.runImport(siteID, r.URL.Query().Get("provider"), tmpfile) // import runs in background and sets busy flag for site
9593

96-
render.Status(r, http.StatusAccepted)
97-
render.JSON(w, r, R.JSON{"status": "import request accepted"})
94+
rest.WriteJSON(w, http.StatusAccepted, R.JSON{"status": "import request accepted"})
9895
}
9996

10097
// GET /wait?site=site-id
@@ -114,14 +111,12 @@ func (m *Migrator) waitCtrl(w http.ResponseWriter, r *http.Request) {
114111

115112
select {
116113
case <-ctx.Done():
117-
render.Status(r, http.StatusGatewayTimeout)
118-
render.JSON(w, r, R.JSON{"status": "timeout expired", "site_id": siteID})
114+
rest.WriteJSON(w, http.StatusGatewayTimeout, R.JSON{"status": "timeout expired", "site_id": siteID})
119115
return
120116
case <-time.After(100 * time.Millisecond):
121117
}
122118
}
123-
render.Status(r, http.StatusOK)
124-
render.JSON(w, r, R.JSON{"status": "completed", "site_id": siteID})
119+
rest.WriteJSON(w, http.StatusOK, R.JSON{"status": "completed", "site_id": siteID})
125120
}
126121

127122
// GET /export?site=site-id&secret=12345&?mode=file|stream
@@ -201,8 +196,7 @@ func (m *Migrator) remapCtrl(w http.ResponseWriter, r *http.Request) {
201196
log.Printf("[DEBUG] convert request completed. site=%s, comments=%d", siteID, size)
202197
}()
203198

204-
render.Status(r, http.StatusAccepted)
205-
render.JSON(w, r, R.JSON{"status": "convert request accepted"})
199+
rest.WriteJSON(w, http.StatusAccepted, R.JSON{"status": "convert request accepted"})
206200
}
207201

208202
// runImport reads from tmpfile and import for given siteID and provider

backend/app/rest/api/rest.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import (
2020
"github.com/go-chi/chi/v5"
2121
"github.com/go-chi/chi/v5/middleware"
2222
"github.com/go-chi/cors"
23-
"github.com/go-chi/render"
2423
"github.com/go-pkgz/auth/v2"
2524
"github.com/go-pkgz/lcw/v2"
2625
log "github.com/go-pkgz/lgr"
@@ -473,8 +472,7 @@ func (s *Rest) configCtrl(w http.ResponseWriter, r *http.Request) {
473472
if cnf.Admins == nil { // prevent json serialization to nil
474473
cnf.Admins = []string{}
475474
}
476-
render.Status(r, http.StatusOK)
477-
render.JSON(w, r, cnf)
475+
rest.WriteJSON(w, http.StatusOK, cnf)
478476
}
479477

480478
// serves static files from the webRoot directory or files embedded into the compiled binary if that directory is absent

backend/app/rest/api/rest_private.go

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import (
1515
"time"
1616

1717
"github.com/go-chi/chi/v5"
18-
"github.com/go-chi/render"
1918
"github.com/go-pkgz/auth/v2"
2019
"github.com/go-pkgz/auth/v2/token"
2120
cache "github.com/go-pkgz/lcw/v2"
@@ -77,7 +76,7 @@ func (s *private) previewCommentCtrl(w http.ResponseWriter, r *http.Request) {
7776
user := rest.MustGetUserInfo(r)
7877

7978
comment := store.Comment{}
80-
if err := render.DecodeJSON(http.MaxBytesReader(w, r.Body, hardBodyLimit), &comment); err != nil {
79+
if err := json.NewDecoder(http.MaxBytesReader(w, r.Body, hardBodyLimit)).Decode(&comment); err != nil {
8180
rest.SendErrorJSON(w, r, http.StatusBadRequest, err, "can't bind comment", rest.ErrDecode)
8281
return
8382
}
@@ -100,14 +99,15 @@ func (s *private) previewCommentCtrl(w http.ResponseWriter, r *http.Request) {
10099
return
101100
}
102101
}
103-
104-
render.HTML(w, r, comment.Text)
102+
w.Header().Set("Content-Type", "text/html; charset=utf-8")
103+
w.WriteHeader(http.StatusOK)
104+
_, _ = w.Write([]byte(comment.Text))
105105
}
106106

107107
// POST /comment - adds comment, resets all immutable fields
108108
func (s *private) createCommentCtrl(w http.ResponseWriter, r *http.Request) {
109109
comment := store.Comment{}
110-
if err := render.DecodeJSON(http.MaxBytesReader(w, r.Body, hardBodyLimit), &comment); err != nil {
110+
if err := json.NewDecoder(http.MaxBytesReader(w, r.Body, hardBodyLimit)).Decode(&comment); err != nil {
111111
rest.SendErrorJSON(w, r, http.StatusBadRequest, err, "can't bind comment", rest.ErrDecode)
112112
return
113113
}
@@ -176,8 +176,7 @@ func (s *private) createCommentCtrl(w http.ResponseWriter, r *http.Request) {
176176

177177
log.Printf("[DEBUG] created comment %+v", finalComment)
178178

179-
render.Status(r, http.StatusCreated)
180-
render.JSON(w, r, &finalComment)
179+
rest.WriteJSON(w, http.StatusCreated, &finalComment)
181180
}
182181

183182
// PUT /comment/{id}?site=siteID&url=post-url - update comment
@@ -188,7 +187,7 @@ func (s *private) updateCommentCtrl(w http.ResponseWriter, r *http.Request) {
188187
Delete bool
189188
}{}
190189

191-
if err := render.DecodeJSON(http.MaxBytesReader(w, r.Body, hardBodyLimit), &edit); err != nil {
190+
if err := json.NewDecoder(http.MaxBytesReader(w, r.Body, hardBodyLimit)).Decode(&edit); err != nil {
192191
rest.SendErrorJSON(w, r, http.StatusBadRequest, err, "can't read comment details from body", rest.ErrDecode)
193192
return
194193
}
@@ -233,7 +232,7 @@ func (s *private) updateCommentCtrl(w http.ResponseWriter, r *http.Request) {
233232
}
234233

235234
s.cache.Flush(cache.Flusher(locator.SiteID).Scopes(locator.SiteID, locator.URL, lastCommentsScope, user.ID))
236-
render.JSON(w, r, res)
235+
rest.WriteJSON(w, http.StatusOK, res)
237236
}
238237

239238
// GET /user?site=siteID - returns user info
@@ -251,7 +250,7 @@ func (s *private) userInfoCtrl(w http.ResponseWriter, r *http.Request) {
251250
}
252251
}
253252

254-
render.JSON(w, r, user)
253+
rest.WriteJSON(w, http.StatusOK, user)
255254
}
256255

257256
// PUT /vote/{id}?site=siteID&url=post-url&vote=1 - vote for/against comment
@@ -292,7 +291,7 @@ func (s *private) voteCtrl(w http.ResponseWriter, r *http.Request) {
292291
return
293292
}
294293
s.cache.Flush(cache.Flusher(locator.SiteID).Scopes(locator.URL, comment.User.ID))
295-
render.JSON(w, r, R.JSON{"id": comment.ID, "score": comment.Score})
294+
rest.WriteJSON(w, http.StatusOK, R.JSON{"id": comment.ID, "score": comment.Score})
296295
}
297296

298297
// getEmailCtrl gets email address for authenticated user.
@@ -305,7 +304,7 @@ func (s *private) getEmailCtrl(w http.ResponseWriter, r *http.Request) {
305304
log.Printf("[WARN] can't read email for %s, %v", user.ID, err)
306305
}
307306

308-
render.JSON(w, r, R.JSON{"user": user, "address": address})
307+
rest.WriteJSON(w, http.StatusOK, R.JSON{"user": user, "address": address})
309308
}
310309

311310
// sendEmailConfirmationCtrl gets address and siteID from query, makes confirmation token and sends it to user.
@@ -322,7 +321,7 @@ func (s *private) sendEmailConfirmationCtrl(w http.ResponseWriter, r *http.Reque
322321
Address string
323322
autoConfirm bool
324323
}{autoConfirm: true}
325-
if err := render.DecodeJSON(http.MaxBytesReader(w, r.Body, hardBodyLimit), &subscribe); err != nil {
324+
if err := json.NewDecoder(http.MaxBytesReader(w, r.Body, hardBodyLimit)).Decode(&subscribe); err != nil {
326325
if err != io.EOF {
327326
rest.SendErrorJSON(w, r, http.StatusBadRequest, err, "can't parse request body", rest.ErrDecode)
328327
return
@@ -385,7 +384,7 @@ func (s *private) sendEmailConfirmationCtrl(w http.ResponseWriter, r *http.Reque
385384
},
386385
)
387386

388-
render.JSON(w, r, R.JSON{"user": user, "address": subscribe.Address, "updated": false})
387+
rest.WriteJSON(w, http.StatusOK, R.JSON{"user": user, "address": subscribe.Address, "updated": false})
389388
}
390389

391390
// telegramSubscribeCtrl generates and verifies telegram notification request
@@ -423,7 +422,7 @@ func (s *private) telegramSubscribeCtrl(w http.ResponseWriter, r *http.Request)
423422

424423
s.telegramService.AddToken(tkn, user.ID, siteID, expires)
425424

426-
render.JSON(w, r, R.JSON{"token": tkn, "bot": s.telegramService.GetBotUsername()})
425+
rest.WriteJSON(w, http.StatusOK, R.JSON{"token": tkn, "bot": s.telegramService.GetBotUsername()})
427426

428427
return
429428
}
@@ -445,7 +444,7 @@ func (s *private) telegramSubscribeCtrl(w http.ResponseWriter, r *http.Request)
445444
return
446445
}
447446

448-
render.JSON(w, r, R.JSON{"updated": true, "address": val})
447+
rest.WriteJSON(w, http.StatusOK, R.JSON{"updated": true, "address": val})
449448
}
450449

451450
// setConfirmedEmailCtrl uses provided token parameter (generated by sendEmailConfirmationCtrl) to set email and add it to user token
@@ -457,7 +456,7 @@ func (s *private) setConfirmedEmailCtrl(w http.ResponseWriter, r *http.Request)
457456
Site string
458457
Token string
459458
}{}
460-
if err := render.DecodeJSON(http.MaxBytesReader(w, r.Body, hardBodyLimit), &confirm); err != nil {
459+
if err := json.NewDecoder(http.MaxBytesReader(w, r.Body, hardBodyLimit)).Decode(&confirm); err != nil {
461460
if err != io.EOF {
462461
rest.SendErrorJSON(w, r, http.StatusBadRequest, err, "can't parse request body", rest.ErrDecode)
463462
return
@@ -513,7 +512,7 @@ func (s *private) setEmail(w http.ResponseWriter, r *http.Request, userID, siteI
513512
rest.SendErrorJSON(w, r, http.StatusInternalServerError, err, "failed to set token", rest.ErrInternal)
514513
return
515514
}
516-
render.JSON(w, r, R.JSON{"updated": true, "address": val})
515+
rest.WriteJSON(w, http.StatusOK, R.JSON{"updated": true, "address": val})
517516
}
518517

519518
// POST/GET /email/unsubscribe.html?site=siteID&tkn=jwt - unsubscribe the user in token from email notifications
@@ -597,7 +596,9 @@ func (s *private) emailUnsubscribeCtrl(w http.ResponseWriter, r *http.Request) {
597596
tmpl := template.Must(template.New("unsubscribe").Parse(tmplstr))
598597
msg := bytes.Buffer{}
599598
MustExecute(tmpl, &msg, nil)
600-
render.HTML(w, r, msg.String())
599+
w.Header().Set("Content-Type", "text/html; charset=utf-8")
600+
w.WriteHeader(http.StatusOK)
601+
_, _ = w.Write(msg.Bytes())
601602
}
602603

603604
// DELETE /email?site=siteID - removes user's email
@@ -624,7 +625,7 @@ func (s *private) deleteEmailCtrl(w http.ResponseWriter, r *http.Request) {
624625
return
625626
}
626627
}
627-
render.JSON(w, r, R.JSON{"deleted": true})
628+
rest.WriteJSON(w, http.StatusOK, R.JSON{"deleted": true})
628629
}
629630

630631
// DELETE /telegram?site=siteID - removes user's telegram
@@ -638,7 +639,7 @@ func (s *private) deleteTelegramCtrl(w http.ResponseWriter, r *http.Request) {
638639
rest.SendErrorJSON(w, r, http.StatusBadRequest, err, "can't delete telegram for user", code)
639640
return
640641
}
641-
render.JSON(w, r, R.JSON{"deleted": true})
642+
rest.WriteJSON(w, http.StatusOK, R.JSON{"deleted": true})
642643
}
643644

644645
// GET /userdata?site=siteID - exports all data about the user as a json with user info and list of all comments
@@ -726,7 +727,7 @@ func (s *private) deleteMeCtrl(w http.ResponseWriter, r *http.Request) {
726727
}
727728

728729
link := fmt.Sprintf("%s/web/deleteme.html?token=%s", s.remarkURL, tokenStr)
729-
render.JSON(w, r, R.JSON{"site": siteID, "user_id": user.ID, "token": tokenStr, "link": link})
730+
rest.WriteJSON(w, http.StatusOK, R.JSON{"site": siteID, "user_id": user.ID, "token": tokenStr, "link": link})
730731
}
731732

732733
// POST /image - save image with form request
@@ -751,7 +752,7 @@ func (s *private) savePictureCtrl(w http.ResponseWriter, r *http.Request) {
751752
return
752753
}
753754

754-
render.JSON(w, r, R.JSON{"id": id})
755+
rest.WriteJSON(w, http.StatusOK, R.JSON{"id": id})
755756
}
756757

757758
func (s *private) isReadOnly(locator store.Locator) bool {

backend/app/rest/api/rest_private_test.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import (
1616
"testing"
1717
"time"
1818

19-
"github.com/go-chi/render"
2019
"github.com/go-pkgz/auth/v2/token"
2120
"github.com/go-pkgz/lgr"
2221
R "github.com/go-pkgz/rest"
@@ -970,7 +969,7 @@ func TestRest_EmailNotification(t *testing.T) {
970969
require.NoError(t, resp.Body.Close())
971970
require.Equal(t, http.StatusCreated, resp.StatusCode, string(body))
972971
parentComment := store.Comment{}
973-
require.NoError(t, render.DecodeJSON(strings.NewReader(string(body)), &parentComment))
972+
require.NoError(t, json.Unmarshal(body, &parentComment))
974973
// wait for mock notification Submit to kick off
975974
time.Sleep(time.Millisecond * 30)
976975
require.Equal(t, 1, len(mockDestination.Get()))
@@ -1220,7 +1219,7 @@ func TestRest_TelegramNotification(t *testing.T) {
12201219
require.NoError(t, resp.Body.Close())
12211220
require.Equal(t, http.StatusCreated, resp.StatusCode, string(body))
12221221
parentComment := store.Comment{}
1223-
require.NoError(t, render.DecodeJSON(strings.NewReader(string(body)), &parentComment))
1222+
require.NoError(t, json.Unmarshal(body, &parentComment))
12241223
// wait for mock notification Submit to kick off
12251224
time.Sleep(time.Millisecond * 30)
12261225
require.Equal(t, 1, len(mockDestination.Get()))

0 commit comments

Comments
 (0)