116 lines
2.2 KiB
Go
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))
|
||
|
}
|
||
|
}
|