10da1a5c6332ec2c9785c99dfee51ddfa8d36558.svn-base 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. package endpoint
  2. import (
  3. "context"
  4. "encoding/json"
  5. "github.com/go-chi/chi"
  6. "net/http"
  7. kitlog "github.com/go-kit/kit/log"
  8. "github.com/prometheus/client_golang/prometheus/promhttp"
  9. shipping "github.com/longjoy/micro-go-course/section19/cargo/model"
  10. "github.com/longjoy/micro-go-course/section19/cargo/service/booking"
  11. "github.com/longjoy/micro-go-course/section19/cargo/service/handling"
  12. "github.com/longjoy/micro-go-course/section19/cargo/service/tracking"
  13. )
  14. // Server holds the dependencies for a HTTP server.
  15. type Server struct {
  16. Booking booking.Service
  17. Tracking tracking.Service
  18. Handling handling.Service
  19. Logger kitlog.Logger
  20. router chi.Router
  21. }
  22. // New returns a new HTTP server.
  23. func New(bs booking.Service, ts tracking.Service, hs handling.Service, logger kitlog.Logger) *Server {
  24. s := &Server{
  25. Booking: bs,
  26. Tracking: ts,
  27. Handling: hs,
  28. Logger: logger,
  29. }
  30. r := chi.NewRouter()
  31. r.Use(accessControl)
  32. r.Route("/booking", func(r chi.Router) {
  33. h := bookingHandler{s.Booking, s.Logger}
  34. r.Mount("/v1", h.router())
  35. })
  36. r.Route("/tracking", func(r chi.Router) {
  37. h := trackingHandler{s.Tracking, s.Logger}
  38. r.Mount("/v1", h.router())
  39. })
  40. r.Route("/handling", func(r chi.Router) {
  41. h := handlingHandler{s.Handling, s.Logger}
  42. r.Mount("/v1", h.router())
  43. })
  44. r.Method("GET", "/metrics", promhttp.Handler())
  45. s.router = r
  46. return s
  47. }
  48. func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  49. s.router.ServeHTTP(w, r)
  50. }
  51. func accessControl(h http.Handler) http.Handler {
  52. return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  53. w.Header().Set("Access-Control-Allow-Origin", "*")
  54. w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
  55. w.Header().Set("Access-Control-Allow-Headers", "Origin, Content-Type")
  56. if r.Method == "OPTIONS" {
  57. return
  58. }
  59. h.ServeHTTP(w, r)
  60. })
  61. }
  62. func encodeError(_ context.Context, err error, w http.ResponseWriter) {
  63. w.Header().Set("Content-Type", "application/json; charset=utf-8")
  64. switch err {
  65. case shipping.ErrUnknownCargo:
  66. w.WriteHeader(http.StatusNotFound)
  67. case tracking.ErrInvalidArgument:
  68. w.WriteHeader(http.StatusBadRequest)
  69. default:
  70. w.WriteHeader(http.StatusInternalServerError)
  71. }
  72. json.NewEncoder(w).Encode(map[string]interface{}{
  73. "error": err.Error(),
  74. })
  75. }