mirror of
https://github.com/EZ-Api/ez-api.git
synced 2026-01-13 17:47:51 +00:00
feat(api): wrap JSON responses in envelope
Add response envelope middleware to standardize JSON responses as
`{code,data,message}` with consistent business codes across endpoints.
Update Swagger annotations and tests to reflect the new response shape.
BREAKING CHANGE: API responses are now wrapped in a response envelope; clients must read payloads from `data` and handle `code`/`message` fields.
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
@@ -9,6 +8,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/alicebob/miniredis/v2"
|
||||
"github.com/ez-api/ez-api/internal/middleware"
|
||||
"github.com/ez-api/ez-api/internal/model"
|
||||
"github.com/ez-api/ez-api/internal/service"
|
||||
"github.com/ez-api/foundation/tokenhash"
|
||||
@@ -58,6 +58,7 @@ func TestAuthHandler_Whoami_InvalidIssuedAtEpoch_Returns401(t *testing.T) {
|
||||
mr.HSet("auth:master:1", "status", "active")
|
||||
|
||||
r := gin.New()
|
||||
r.Use(middleware.ResponseEnvelope())
|
||||
r.GET("/auth/whoami", handler.Whoami)
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/auth/whoami", nil)
|
||||
@@ -83,6 +84,7 @@ func TestAuthHandler_Whoami_InvalidMasterEpoch_Returns401(t *testing.T) {
|
||||
mr.HSet("auth:master:1", "status", "active")
|
||||
|
||||
r := gin.New()
|
||||
r.Use(middleware.ResponseEnvelope())
|
||||
r.GET("/auth/whoami", handler.Whoami)
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/auth/whoami", nil)
|
||||
@@ -128,6 +130,7 @@ func TestAuthHandler_Whoami_KeyResponseIncludesIPRules(t *testing.T) {
|
||||
}
|
||||
|
||||
r := gin.New()
|
||||
r.Use(middleware.ResponseEnvelope())
|
||||
r.GET("/auth/whoami", handler.Whoami)
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/auth/whoami", nil)
|
||||
@@ -140,8 +143,12 @@ func TestAuthHandler_Whoami_KeyResponseIncludesIPRules(t *testing.T) {
|
||||
}
|
||||
|
||||
var resp map[string]any
|
||||
if err := json.Unmarshal(rr.Body.Bytes(), &resp); err != nil {
|
||||
t.Fatalf("decode response: %v", err)
|
||||
env := decodeEnvelope(t, rr, &resp)
|
||||
if env.Code != "ok" {
|
||||
t.Fatalf("expected code=ok, got %q", env.Code)
|
||||
}
|
||||
if env.Message != "" {
|
||||
t.Fatalf("expected empty message, got %q", env.Message)
|
||||
}
|
||||
if resp["allow_ips"] != "1.2.3.4" {
|
||||
t.Fatalf("expected allow_ips, got %v", resp["allow_ips"])
|
||||
@@ -187,6 +194,7 @@ func TestAuthHandler_Whoami_ExpiredKey_Returns401(t *testing.T) {
|
||||
}
|
||||
|
||||
r := gin.New()
|
||||
r.Use(middleware.ResponseEnvelope())
|
||||
r.GET("/auth/whoami", handler.Whoami)
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/auth/whoami", nil)
|
||||
@@ -199,8 +207,12 @@ func TestAuthHandler_Whoami_ExpiredKey_Returns401(t *testing.T) {
|
||||
}
|
||||
|
||||
var resp map[string]any
|
||||
if err := json.Unmarshal(rr.Body.Bytes(), &resp); err != nil {
|
||||
t.Fatalf("decode response: %v", err)
|
||||
env := decodeEnvelope(t, rr, &resp)
|
||||
if env.Code != "unauthorized" {
|
||||
t.Fatalf("expected code=unauthorized, got %q", env.Code)
|
||||
}
|
||||
if env.Message != "token has expired" {
|
||||
t.Fatalf("expected message 'token has expired', got %q", env.Message)
|
||||
}
|
||||
if resp["error"] != "token has expired" {
|
||||
t.Fatalf("expected 'token has expired' error, got %v", resp["error"])
|
||||
|
||||
Reference in New Issue
Block a user