testgo4/pkg/httpresponse/envelope.go
jordan 102d1167f2
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
ci/woodpecker/manual/woodpecker Pipeline was successful
Initialize project from skeleton template
2026-02-01 20:53:33 +00:00

76 lines
1.9 KiB
Go

// Package httpresponse provides standard HTTP response types and helpers.
//
// This package implements an envelope pattern for consistent API responses:
//
// {
// "data": {...}, // Present on success
// "error": {...}, // Present on error
// "meta": {
// "request_id": "...",
// "trace_id": "...",
// "timestamp": "..."
// }
// }
//
// Usage:
//
// func GetUser(w http.ResponseWriter, r *http.Request) {
// user, err := svc.Get(ctx, id)
// if err != nil {
// httpresponse.NotFound(w, r, "user not found")
// return
// }
// httpresponse.OK(w, r, user)
// }
package httpresponse
import (
"net/http"
"time"
"git.threesix.ai/jordan/testgo4/pkg/httpcontext"
)
// Response is the standard envelope for all API responses.
type Response struct {
Data any `json:"data,omitempty"`
Error *Error `json:"error,omitempty"`
Meta Meta `json:"meta"`
}
// Error represents an API error in the response envelope.
type Error struct {
Code string `json:"code"`
Message string `json:"message"`
Details any `json:"details,omitempty"`
}
// Meta contains response metadata.
type Meta struct {
RequestID string `json:"request_id,omitempty"`
TraceID string `json:"trace_id,omitempty"`
Timestamp string `json:"timestamp"`
}
// newMeta creates a Meta with current timestamp, request ID, and trace ID from context.
func newMeta(r *http.Request) Meta {
requestID, _ := httpcontext.GetRequestID(r.Context())
traceID, _ := httpcontext.GetTraceID(r.Context())
return Meta{
RequestID: requestID,
TraceID: traceID,
Timestamp: time.Now().UTC().Format(time.RFC3339),
}
}
// Error codes for machine-readable error classification.
const (
CodeBadRequest = "BAD_REQUEST"
CodeUnauthorized = "UNAUTHORIZED"
CodeForbidden = "FORBIDDEN"
CodeNotFound = "NOT_FOUND"
CodeConflict = "CONFLICT"
CodeInternal = "INTERNAL_ERROR"
CodeValidation = "VALIDATION_ERROR"
)