Skip to content

Commit

Permalink
add a pair of encode/decode json functions
Browse files Browse the repository at this point in the history
  • Loading branch information
umputun committed Feb 9, 2024
1 parent e99c97b commit 7f7ba91
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 5 deletions.
20 changes: 19 additions & 1 deletion rest.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
)

// JSON is a map alias, just for convenience
type JSON map[string]interface{}
type JSON map[string]any

// RenderJSON sends data as json
func RenderJSON(w http.ResponseWriter, data interface{}) {
Expand Down Expand Up @@ -97,3 +97,21 @@ func ParseFromTo(r *http.Request) (from, to time.Time, err error) {
}
return from, to, nil
}

// DecodeJSON decodes json request from http.Request to given type
func DecodeJSON[T any](r *http.Request, res *T) error {
if err := json.NewDecoder(r.Body).Decode(&res); err != nil {
return fmt.Errorf("decode json: %w", err)
}
return nil
}

// EncodeJSON encodes given type to http.ResponseWriter and sets status code and content type header
func EncodeJSON[T any](w http.ResponseWriter, status int, v T) error {
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.WriteHeader(status)
if err := json.NewEncoder(w).Encode(v); err != nil {
return fmt.Errorf("encode json: %w", err)
}
return nil
}
48 changes: 44 additions & 4 deletions rest_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package rest

import (
"bytes"
"encoding/json"
"errors"
"io"
Expand All @@ -15,7 +16,6 @@ import (
)

func TestRest_RenderJSON(t *testing.T) {

ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
j := JSON{"key1": 1, "key2": "222"}
RenderJSON(w, j)
Expand All @@ -35,7 +35,6 @@ func TestRest_RenderJSON(t *testing.T) {
}

func TestRest_RenderJSONFromBytes(t *testing.T) {

ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
require.NoError(t, RenderJSONFromBytes(w, r, []byte("some data")))
}))
Expand All @@ -53,7 +52,6 @@ func TestRest_RenderJSONFromBytes(t *testing.T) {
}

func TestRest_RenderJSONWithHTML(t *testing.T) {

ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
j := JSON{"key1": "val1", "key2": 2.0, "html": `<div> blah </div>`}
require.NoError(t, RenderJSONWithHTML(w, r, j))
Expand All @@ -77,7 +75,6 @@ func TestRest_RenderJSONWithHTML(t *testing.T) {
}

func TestParseFromTo(t *testing.T) {

tbl := []struct {
query string
from, to time.Time
Expand Down Expand Up @@ -123,6 +120,49 @@ func TestParseFromTo(t *testing.T) {

}

func TestDecodeJSONRequest(t *testing.T) {
type record struct {
Field1 string `json:"field1"`
Field2 int `json:"field2"`
}

inp := `{"field1":"value1","field2":2}`
req := httptest.NewRequest(http.MethodPost, "/test", bytes.NewBufferString(inp))
req.Header.Set("Content-Type", "application/json")

var obj record
err := DecodeJSON(req, &obj)
require.NoError(t, err)
assert.Equal(t, "value1", obj.Field1)
assert.Equal(t, 2, obj.Field2)
}

func TestEncodeJSONResponse(t *testing.T) {
type record struct {
Field1 string `json:"field1"`
Field2 int `json:"field2"`
}

obj := record{Field1: "value1", Field2: 2}
w := httptest.NewRecorder()
if err := EncodeJSON(w, http.StatusOK, obj); err != nil {
t.Errorf("Failed to encode JSON response: %v", err)
}

resp := w.Result()
defer resp.Body.Close()

assert.Equal(t, http.StatusOK, resp.StatusCode)
assert.Equal(t, "application/json; charset=utf-8", resp.Header.Get("Content-Type"))

var decodedObj record
err := json.NewDecoder(resp.Body).Decode(&decodedObj)
require.NoError(t, err)

assert.Equal(t, obj.Field1, decodedObj.Field1)
assert.Equal(t, obj.Field2, decodedObj.Field2)
}

func getTestHandlerBlah() http.HandlerFunc {
fn := func(rw http.ResponseWriter, req *http.Request) {

Check warning on line 167 in rest_test.go

View workflow job for this annotation

GitHub Actions / build

unused-parameter: parameter 'req' seems to be unused, consider removing or renaming it as _ (revive)
_, _ = rw.Write([]byte("blah"))
Expand Down

0 comments on commit 7f7ba91

Please sign in to comment.