common.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. package api
  2. import (
  3. "encoding/json"
  4. "net/http"
  5. "github.com/grafana/grafana/pkg/middleware"
  6. "github.com/grafana/grafana/pkg/setting"
  7. "gopkg.in/macaron.v1"
  8. )
  9. var (
  10. NotFound = func() Response {
  11. return ApiError(404, "Not found", nil)
  12. }
  13. ServerError = func(err error) Response {
  14. return ApiError(500, "Server error", err)
  15. }
  16. )
  17. type Response interface {
  18. WriteTo(ctx *middleware.Context)
  19. }
  20. type NormalResponse struct {
  21. status int
  22. body []byte
  23. header http.Header
  24. errMessage string
  25. err error
  26. }
  27. func wrap(action interface{}) macaron.Handler {
  28. return func(c *middleware.Context) {
  29. var res Response
  30. val, err := c.Invoke(action)
  31. if err == nil && val != nil && len(val) > 0 {
  32. res = val[0].Interface().(Response)
  33. } else {
  34. res = ServerError(err)
  35. }
  36. res.WriteTo(c)
  37. }
  38. }
  39. func (r *NormalResponse) WriteTo(ctx *middleware.Context) {
  40. if r.err != nil {
  41. ctx.Logger.Error(r.errMessage, "error", r.err)
  42. }
  43. header := ctx.Resp.Header()
  44. for k, v := range r.header {
  45. header[k] = v
  46. }
  47. ctx.Resp.WriteHeader(r.status)
  48. ctx.Resp.Write(r.body)
  49. }
  50. func (r *NormalResponse) Cache(ttl string) *NormalResponse {
  51. return r.Header("Cache-Control", "public,max-age="+ttl)
  52. }
  53. func (r *NormalResponse) Header(key, value string) *NormalResponse {
  54. r.header.Set(key, value)
  55. return r
  56. }
  57. // functions to create responses
  58. func Empty(status int) *NormalResponse {
  59. return Respond(status, nil)
  60. }
  61. func Json(status int, body interface{}) *NormalResponse {
  62. return Respond(status, body).Header("Content-Type", "application/json")
  63. }
  64. func ApiSuccess(message string) *NormalResponse {
  65. resp := make(map[string]interface{})
  66. resp["message"] = message
  67. return Json(200, resp)
  68. }
  69. func ApiError(status int, message string, err error) *NormalResponse {
  70. data := make(map[string]interface{})
  71. switch status {
  72. case 404:
  73. data["message"] = "Not Found"
  74. case 500:
  75. data["message"] = "Internal Server Error"
  76. }
  77. if message != "" {
  78. data["message"] = message
  79. }
  80. if err != nil {
  81. if setting.Env != setting.PROD {
  82. data["error"] = err.Error()
  83. }
  84. }
  85. resp := Json(status, data)
  86. if err != nil {
  87. resp.errMessage = message
  88. resp.err = err
  89. }
  90. return resp
  91. }
  92. func Respond(status int, body interface{}) *NormalResponse {
  93. var b []byte
  94. var err error
  95. switch t := body.(type) {
  96. case []byte:
  97. b = t
  98. case string:
  99. b = []byte(t)
  100. default:
  101. if b, err = json.Marshal(body); err != nil {
  102. return ApiError(500, "body json marshal", err)
  103. }
  104. }
  105. return &NormalResponse{
  106. body: b,
  107. status: status,
  108. header: make(http.Header),
  109. }
  110. }