You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

56 lines
1.4 KiB

  1. package response
  2. import (
  3. "encoding/json"
  4. "log/slog"
  5. "net/http"
  6. )
  7. // ErrorBody is the standard JSON error response shape.
  8. type ErrorBody struct {
  9. Error string `json:"error"`
  10. Message string `json:"message,omitempty"`
  11. }
  12. // JSON writes a JSON body with status code and Content-Type.
  13. func JSON(w http.ResponseWriter, status int, v any) {
  14. w.Header().Set("Content-Type", "application/json")
  15. w.WriteHeader(status)
  16. if v != nil {
  17. _ = json.NewEncoder(w).Encode(v)
  18. }
  19. }
  20. // OK writes 200 with optional JSON body.
  21. func OK(w http.ResponseWriter, v any) {
  22. if v == nil {
  23. w.WriteHeader(http.StatusOK)
  24. w.Write([]byte("ok"))
  25. return
  26. }
  27. JSON(w, http.StatusOK, v)
  28. }
  29. // Error writes a JSON error response.
  30. func Error(w http.ResponseWriter, status int, err string, message string) {
  31. JSON(w, status, ErrorBody{Error: err, Message: message})
  32. }
  33. // BadRequest writes 400 with error message.
  34. func BadRequest(w http.ResponseWriter, message string) {
  35. Error(w, http.StatusBadRequest, "bad_request", message)
  36. }
  37. // InternalError writes 500 and logs the err.
  38. func InternalError(w http.ResponseWriter, message string, logErr error) {
  39. if logErr != nil {
  40. slog.Error(message, "err", logErr)
  41. }
  42. Error(w, http.StatusInternalServerError, "internal_error", message)
  43. }
  44. // NotFound writes 404.
  45. func NotFound(w http.ResponseWriter, message string) {
  46. Error(w, http.StatusNotFound, "not_found", message)
  47. }