Skip to content

Commit

Permalink
Merge pull request #5 from alexzimmer96/master
Browse files Browse the repository at this point in the history
Adding support for default http-messages
  • Loading branch information
nicklaw5 authored Jun 30, 2019
2 parents 466cc16 + 1fb9543 commit 3bbdd46
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 3 deletions.
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,34 @@ See [here](https://httpstatuses.com/) for a complete list of HTTP responses, alo

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

## To Long, Don't Write

Sometimes you don't need to return a specific content-message but don't want the response body to be empty.
In this case you can use the `DefaultMessage()` for responding with json containing the default message for the corresponding status code.

```go
package main

import (
"net/http"
resp "github.com/nicklaw5/go-respond"
)

func main() {
http.HandleFunc("/api/users", func(w http.ResponseWriter, r *http.Request) {
// ...
if !authenticated {
resp.NewResponse(w).DefaultMessage().
Unauthorized(nil)
}
// ...
})
http.ListenAndServe(":8080", nil)
}
```

Would respond with `{"status":401,"message":"Unauthorized"}`

## Handling Errors

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:
Expand Down
26 changes: 23 additions & 3 deletions response.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,15 @@ import (

// Response is the HTTP response
type Response struct {
Writer http.ResponseWriter
Headers map[string]string
Writer http.ResponseWriter
Headers map[string]string
DefMessage bool
}

// DefaultMessageResponse is for transporting a default http message
type DefaultMessageResponse struct {
Status int `json:"status"`
Message string `json:"message"`
}

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

func (resp *Response) DefaultMessage() *Response {
resp.DefMessage = true
return resp
}

// DeleteHeader deletes a single header from the response
func (resp *Response) DeleteHeader(key string) *Response {
resp.Writer.Header().Del(key)
Expand All @@ -41,16 +53,24 @@ func (resp *Response) writeResponse(code int, v interface{}) error {

resp.writeStatusCode(code)

if v == nil && resp.DefMessage {
v = DefaultMessageResponse{
Status: code,
Message: http.StatusText(code),
}
}

if v != nil {
body, err := json.Marshal(v)
if err != nil {
panic(err)
}

// can just return an error when connection is hijacked or content-size is longer then declared.
if _, err := resp.Writer.Write(body); err != nil {
panic(err)
}
}

return nil
}

Expand Down
36 changes: 36 additions & 0 deletions response_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,42 @@ func validateResponseHeader(responseHeaderValue string, expectedHeaderValue stri
return nil
}

func TestDefaultMessage(t *testing.T) {
t.Parallel()

req := newRequest(t, "GET")

rr := httptest.NewRecorder()
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
NewResponse(w).DefaultMessage().
Unauthorized(nil)
})
handler.ServeHTTP(rr, req)

if err := validateResponseBody(rr.Body.String(), "{\"status\":401,\"message\":\"Unauthorized\"}"); err != nil {
t.Fatal(err)
}
}

func TestRespondInvalidType(t *testing.T) {
defer func() {
if r := recover(); r == nil {
t.Errorf("responding with invalid type (channel) should have caused a panic")
}
}()

t.Parallel()

req := newRequest(t, "GET")

rr := httptest.NewRecorder()
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
NewResponse(w).DefaultMessage().
Unauthorized(make(chan int))
})
handler.ServeHTTP(rr, req)
}

func TestContentTypeHeader(t *testing.T) {
t.Parallel()

Expand Down

0 comments on commit 3bbdd46

Please sign in to comment.