Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions response_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,18 @@ func (b *ReplyBuilder) Created(w http.ResponseWriter, data any, location string)
builder.Write(w)
}

// Accepted writes a 202 JSON response using the fluent helper configuration.
func (b *ReplyBuilder) Accepted(w http.ResponseWriter, data any) {
Respond(data).Status(http.StatusAccepted).Meta(b.meta).Headers(b.headers).Write(w)
}

// NoContent writes a 204 response with no body using the fluent helper configuration.
// Metadata is ignored because a 204 response must not carry a body.
func (b *ReplyBuilder) NoContent(w http.ResponseWriter) {
applyHeaders(w, b.headers)
w.WriteHeader(http.StatusNoContent)
}

// Problem writes a problem response using the fluent helper configuration.
func (b *ReplyBuilder) Problem(w http.ResponseWriter, problem *ProblemDetails) {
RespondProblem(problem).Headers(b.headers).Write(w)
Expand Down
10 changes: 10 additions & 0 deletions response_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,16 @@ func Created[T any](w http.ResponseWriter, data T, location string) {
Reply().Created(w, data, location)
}

// Accepted writes a 202 JSON response without metadata.
func Accepted[T any](w http.ResponseWriter, data T) {
Reply().Accepted(w, data)
}

// NoContent writes a 204 response with no body.
func NoContent(w http.ResponseWriter) {
Reply().NoContent(w)
}

// ProblemResponse writes a problem response using the problem's status.
func ProblemResponse(w http.ResponseWriter, problem *ProblemDetails) {
if problem == nil {
Expand Down
42 changes: 42 additions & 0 deletions response_helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,48 @@ func TestResponseHelpers(t *testing.T) {
}
})

t.Run("accepted helper", func(t *testing.T) {
w := httptest.NewRecorder()
Accepted(w, testResponse{Key: "value"})
if w.Code != http.StatusAccepted {
t.Fatalf("expected status %d, got %d", http.StatusAccepted, w.Code)
}
if w.Body.Len() == 0 {
t.Fatal("expected response body")
}
})

t.Run("no content helper", func(t *testing.T) {
w := httptest.NewRecorder()
NoContent(w)
if w.Code != http.StatusNoContent {
t.Fatalf("expected status %d, got %d", http.StatusNoContent, w.Code)
}
if w.Body.Len() != 0 {
t.Fatalf("expected empty body, got %q", w.Body.String())
}
})

t.Run("reply builder accepted and no content", func(t *testing.T) {
w := httptest.NewRecorder()
Reply().Header("X-Job", "1").Meta(map[string]int{"n": 1}).Accepted(w, testResponse{Key: "value"})
if w.Code != http.StatusAccepted || w.Header().Get("X-Job") != "1" {
t.Fatalf("unexpected accepted response: %d %v", w.Code, w.Header())
}

w = httptest.NewRecorder()
Reply().Header("X-Job", "2").NoContent(w)
if w.Code != http.StatusNoContent || w.Header().Get("X-Job") != "2" {
t.Fatalf("unexpected no content response: %d %v", w.Code, w.Header())
}
if w.Body.Len() != 0 {
t.Fatalf("expected empty body, got %q", w.Body.String())
}
if ct := w.Header().Get("Content-Type"); ct != "" {
t.Fatalf("expected no content type, got %q", ct)
}
})

t.Run("problem helper", func(t *testing.T) {
w := httptest.NewRecorder()
ProblemResponse(w, NewNotFoundProblem("user missing"))
Expand Down
Loading