blk/internal/controller/http/http.go
2024-08-11 04:52:08 +03:00

116 lines
2.2 KiB
Go

package http
import (
"encoding/json"
"log/slog"
"net/http"
"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
"github.com/optclblast/blk/internal/logger"
)
// router object
type router struct {
*chi.Mux
log *slog.Logger
walletsController WalletsController
}
// NewRouter returns a new http.Handler object that can power your server
func NewRouter(
log *slog.Logger,
walletsController WalletsController,
) http.Handler {
r := &router{
Mux: chi.NewRouter(),
log: log,
walletsController: walletsController,
}
r.Use(middleware.Recoverer)
r.Use(handleMw)
r.Get("/most-changed", r.handle(
r.walletsController.MostChangedWalletAddress,
"most-changed",
))
return r
}
// handleMw adds content type headers
func handleMw(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Add("Content-Type", "application/json")
next.ServeHTTP(w, r)
})
}
type handleFunc func(w http.ResponseWriter, req *http.Request) (any, error)
// handle is a helper functions that makes it easier to work with http handlers
func (s *router) handle(
h handleFunc,
method_name string,
) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
resp, err := h(w, r)
if err != nil {
s.log.Error(
"http error",
slog.String("method_name", method_name),
logger.Err(err),
)
s.responseError(w, err)
return
}
out, err := json.Marshal(resp)
if err != nil {
s.log.Error(
"error marshal response",
slog.String("method_name", method_name),
logger.Err(err),
slog.Any("object", resp),
)
s.responseError(w, err)
return
}
w.WriteHeader(http.StatusOK)
if _, err = w.Write(out); err != nil {
s.log.Error(
"error write http response",
slog.String("method_name", method_name),
logger.Err(err),
)
}
}
}
func (s *router) responseError(
w http.ResponseWriter,
e error,
) {
apiErr := mapError(e)
out, err := json.Marshal(apiErr)
if err != nil {
return
}
w.WriteHeader(apiErr.Code)
if _, err := w.Write(out); err != nil {
s.log.Error("error write error to connection", logger.Err(err))
}
}