Files
uPortal2/backend/internal/rest/response.go
T
2026-10-21 19:41:26 +03:00

67 lines
1.4 KiB
Go

package rest
import (
"encoding/json"
"io"
"log/slog"
"net/http"
"strconv"
)
const (
maxRequestBody = 1 << 20
defaultLimit = 50
maxLimit = 200
)
type errorResponse struct {
Error string `json:"error"`
}
func writeJson(w http.ResponseWriter, status int, value any) {
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.WriteHeader(status)
if value == nil {
return
}
if err := json.NewEncoder(w).Encode(value); err != nil {
slog.Error("encode response", slog.String("op", "rest.writeJson"), slog.Any("error", err))
}
}
func writeError(w http.ResponseWriter, status int, message string) {
writeJson(w, status, errorResponse{Error: message})
}
func writeNoContent(w http.ResponseWriter) {
w.WriteHeader(http.StatusNoContent)
}
func decodeJson(r *http.Request, dst any) error {
decoder := json.NewDecoder(io.LimitReader(r.Body, maxRequestBody))
decoder.DisallowUnknownFields()
return decoder.Decode(dst)
}
func pagination(r *http.Request) (limit, offset int64) {
limit = defaultLimit
query := r.URL.Query()
if value := query.Get("limit"); value != "" {
if parsed, err := strconv.ParseInt(value, 10, 64); err == nil && parsed > 0 {
limit = parsed
}
}
if limit > maxLimit {
limit = maxLimit
}
if value := query.Get("offset"); value != "" {
if parsed, err := strconv.ParseInt(value, 10, 64); err == nil && parsed >= 0 {
offset = parsed
}
}
return limit, offset
}