Skip to content

Commit 3bbdd46

Browse files
authored
Merge pull request #5 from alexzimmer96/master
Adding support for default http-messages
2 parents 466cc16 + 1fb9543 commit 3bbdd46

3 files changed

Lines changed: 87 additions & 3 deletions

File tree

README.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,34 @@ See [here](https://httpstatuses.com/) for a complete list of HTTP responses, alo
7373

7474
Please submit a PR if you want to add to this list. Only the most common response types have been included.
7575

76+
## To Long, Don't Write
77+
78+
Sometimes you don't need to return a specific content-message but don't want the response body to be empty.
79+
In this case you can use the `DefaultMessage()` for responding with json containing the default message for the corresponding status code.
80+
81+
```go
82+
package main
83+
84+
import (
85+
"net/http"
86+
resp "github.com/nicklaw5/go-respond"
87+
)
88+
89+
func main() {
90+
http.HandleFunc("/api/users", func(w http.ResponseWriter, r *http.Request) {
91+
// ...
92+
if !authenticated {
93+
resp.NewResponse(w).DefaultMessage().
94+
Unauthorized(nil)
95+
}
96+
// ...
97+
})
98+
http.ListenAndServe(":8080", nil)
99+
}
100+
```
101+
102+
Would respond with `{"status":401,"message":"Unauthorized"}`
103+
76104
## Handling Errors
77105

78106
The best option for handling errors that may occur while marshalling the JSON response, is to use [Negroni's Recovery middleware](https://github.com/urfave/negroni#recovery). Here's an example:

response.go

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,15 @@ import (
77

88
// Response is the HTTP response
99
type Response struct {
10-
Writer http.ResponseWriter
11-
Headers map[string]string
10+
Writer http.ResponseWriter
11+
Headers map[string]string
12+
DefMessage bool
13+
}
14+
15+
// DefaultMessageResponse is for transporting a default http message
16+
type DefaultMessageResponse struct {
17+
Status int `json:"status"`
18+
Message string `json:"message"`
1219
}
1320

1421
// NewResponse creates and returns a new response
@@ -21,6 +28,11 @@ func NewResponse(w http.ResponseWriter) *Response {
2128
}
2229
}
2330

31+
func (resp *Response) DefaultMessage() *Response {
32+
resp.DefMessage = true
33+
return resp
34+
}
35+
2436
// DeleteHeader deletes a single header from the response
2537
func (resp *Response) DeleteHeader(key string) *Response {
2638
resp.Writer.Header().Del(key)
@@ -41,16 +53,24 @@ func (resp *Response) writeResponse(code int, v interface{}) error {
4153

4254
resp.writeStatusCode(code)
4355

56+
if v == nil && resp.DefMessage {
57+
v = DefaultMessageResponse{
58+
Status: code,
59+
Message: http.StatusText(code),
60+
}
61+
}
62+
4463
if v != nil {
4564
body, err := json.Marshal(v)
4665
if err != nil {
4766
panic(err)
4867
}
49-
68+
// can just return an error when connection is hijacked or content-size is longer then declared.
5069
if _, err := resp.Writer.Write(body); err != nil {
5170
panic(err)
5271
}
5372
}
73+
5474
return nil
5575
}
5676

response_test.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,42 @@ func validateResponseHeader(responseHeaderValue string, expectedHeaderValue stri
4040
return nil
4141
}
4242

43+
func TestDefaultMessage(t *testing.T) {
44+
t.Parallel()
45+
46+
req := newRequest(t, "GET")
47+
48+
rr := httptest.NewRecorder()
49+
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
50+
NewResponse(w).DefaultMessage().
51+
Unauthorized(nil)
52+
})
53+
handler.ServeHTTP(rr, req)
54+
55+
if err := validateResponseBody(rr.Body.String(), "{\"status\":401,\"message\":\"Unauthorized\"}"); err != nil {
56+
t.Fatal(err)
57+
}
58+
}
59+
60+
func TestRespondInvalidType(t *testing.T) {
61+
defer func() {
62+
if r := recover(); r == nil {
63+
t.Errorf("responding with invalid type (channel) should have caused a panic")
64+
}
65+
}()
66+
67+
t.Parallel()
68+
69+
req := newRequest(t, "GET")
70+
71+
rr := httptest.NewRecorder()
72+
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
73+
NewResponse(w).DefaultMessage().
74+
Unauthorized(make(chan int))
75+
})
76+
handler.ServeHTTP(rr, req)
77+
}
78+
4379
func TestContentTypeHeader(t *testing.T) {
4480
t.Parallel()
4581

0 commit comments

Comments
 (0)