package utils import ( "encoding/json" "errors" "fmt" "io" "net/http" "strings" ) func RespondWithJSON(w http.ResponseWriter, statusCode int, data interface{}) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(statusCode) json.NewEncoder(w).Encode(data) } func RespondWithError(w http.ResponseWriter, statusCode int, message string) { RespondWithJSON(w, statusCode, map[string]string{"error": message}) } // DecodeJSONBody декодирует JSON тело запроса func DecodeJSONBody(w http.ResponseWriter, r *http.Request, dst interface{}) error { if r.Header.Get("Content-Type") != "application/json" { return errors.New("Content-Type header is not application/json") } r.Body = http.MaxBytesReader(w, r.Body, 1048576) // 1MB limit dec := json.NewDecoder(r.Body) dec.DisallowUnknownFields() err := dec.Decode(dst) if err != nil { var syntaxError *json.SyntaxError var unmarshalTypeError *json.UnmarshalTypeError switch { case errors.As(err, &syntaxError): return fmt.Errorf("request body contains badly-formed JSON (at position %d)", syntaxError.Offset) case errors.Is(err, io.ErrUnexpectedEOF): return errors.New("request body contains badly-formed JSON") case errors.As(err, &unmarshalTypeError): return fmt.Errorf("request body contains an invalid value for the %q field (at position %d)", unmarshalTypeError.Field, unmarshalTypeError.Offset) case strings.HasPrefix(err.Error(), "json: unknown field "): fieldName := strings.TrimPrefix(err.Error(), "json: unknown field ") return fmt.Errorf("request body contains unknown field %s", fieldName) case errors.Is(err, io.EOF): return errors.New("request body must not be empty") case err.Error() == "http: request body too large": return errors.New("request body must not be larger than 1MB") default: return err } } err = dec.Decode(&struct{}{}) if err != io.EOF { return errors.New("request body must only contain a single JSON object") } return nil } // GetUserIDFromContext извлекает userID из контекста func GetUserIDFromContext(r *http.Request) (uint, bool) { userID, ok := r.Context().Value("userID").(uint) return userID, ok }