2024-01-23 07:13:55 +00:00
|
|
|
package port
|
|
|
|
|
|
|
|
import (
|
|
|
|
"net/http"
|
|
|
|
"sync"
|
|
|
|
|
2024-01-27 08:37:12 +00:00
|
|
|
"gitea.dwysokinski.me/twhelp/corev3/internal/app"
|
2024-01-23 07:13:55 +00:00
|
|
|
"gitea.dwysokinski.me/twhelp/corev3/internal/port/internal/apimodel"
|
|
|
|
"gitea.dwysokinski.me/twhelp/corev3/internal/port/internal/swgui"
|
|
|
|
"github.com/getkin/kin-openapi/openapi3"
|
|
|
|
"github.com/go-chi/chi/v5"
|
2024-01-31 07:14:18 +00:00
|
|
|
"github.com/go-chi/chi/v5/middleware"
|
2024-01-23 07:13:55 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type apiHTTPHandler struct {
|
2024-03-11 06:41:32 +00:00
|
|
|
versionSvc *app.VersionService
|
|
|
|
serverSvc *app.ServerService
|
|
|
|
tribeSvc *app.TribeService
|
|
|
|
playerSvc *app.PlayerService
|
|
|
|
villageSvc *app.VillageService
|
|
|
|
ennoblementSvc *app.EnnoblementService
|
2024-03-13 07:23:22 +00:00
|
|
|
tribeChangeSvc *app.TribeChangeService
|
2024-03-11 06:41:32 +00:00
|
|
|
errorRenderer apiErrorRenderer
|
|
|
|
openAPISchema func() (*openapi3.T, error)
|
2024-01-23 07:13:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func WithOpenAPIConfig(oapiCfg OpenAPIConfig) APIHTTPHandlerOption {
|
|
|
|
return func(cfg *apiHTTPHandlerConfig) {
|
|
|
|
cfg.openAPI = oapiCfg
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-09 11:30:01 +00:00
|
|
|
func NewAPIHTTPHandler(
|
|
|
|
versionSvc *app.VersionService,
|
|
|
|
serverSvc *app.ServerService,
|
2024-02-14 06:43:55 +00:00
|
|
|
tribeSvc *app.TribeService,
|
2024-02-26 07:15:11 +00:00
|
|
|
playerSvc *app.PlayerService,
|
2024-03-05 06:42:37 +00:00
|
|
|
villageSvc *app.VillageService,
|
2024-03-11 06:41:32 +00:00
|
|
|
ennoblementSvc *app.EnnoblementService,
|
2024-03-13 07:23:22 +00:00
|
|
|
tribeChangeSvc *app.TribeChangeService,
|
2024-02-09 11:30:01 +00:00
|
|
|
opts ...APIHTTPHandlerOption,
|
|
|
|
) http.Handler {
|
2024-01-23 07:13:55 +00:00
|
|
|
cfg := newAPIHTTPHandlerConfig(opts...)
|
|
|
|
|
|
|
|
h := &apiHTTPHandler{
|
2024-03-11 06:41:32 +00:00
|
|
|
versionSvc: versionSvc,
|
|
|
|
serverSvc: serverSvc,
|
|
|
|
tribeSvc: tribeSvc,
|
|
|
|
playerSvc: playerSvc,
|
|
|
|
villageSvc: villageSvc,
|
|
|
|
ennoblementSvc: ennoblementSvc,
|
2024-03-13 07:23:22 +00:00
|
|
|
tribeChangeSvc: tribeChangeSvc,
|
2024-01-31 07:14:18 +00:00
|
|
|
openAPISchema: sync.OnceValues(func() (*openapi3.T, error) {
|
2024-01-23 07:13:55 +00:00
|
|
|
return getOpenAPISchema(cfg.openAPI)
|
|
|
|
}),
|
|
|
|
}
|
|
|
|
|
|
|
|
r := chi.NewRouter()
|
|
|
|
|
|
|
|
if cfg.openAPI.Enabled {
|
|
|
|
r.Group(func(r chi.Router) {
|
|
|
|
if cfg.openAPI.SwaggerEnabled {
|
2024-01-31 07:14:18 +00:00
|
|
|
r.HandleFunc("/v2/swagger", func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
http.Redirect(w, r, r.RequestURI+"/", http.StatusMovedPermanently)
|
|
|
|
})
|
2024-01-23 07:13:55 +00:00
|
|
|
r.Handle("/v2/swagger/*", swgui.Handler(
|
|
|
|
cfg.openAPI.BasePath+"/v2/swagger",
|
|
|
|
cfg.openAPI.BasePath+"/v2/openapi3.json",
|
|
|
|
))
|
|
|
|
}
|
|
|
|
r.Get("/v2/openapi3.json", h.sendOpenAPIJSON)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2024-01-31 07:14:18 +00:00
|
|
|
// these handlers must be set after the swagger/openapi routes
|
2024-02-25 07:31:13 +00:00
|
|
|
// because we don't want to override the default handlers for those routes
|
2024-01-31 07:14:18 +00:00
|
|
|
r.NotFound(h.handleNotFound)
|
|
|
|
r.MethodNotAllowed(h.handleMethodNotAllowed)
|
|
|
|
|
|
|
|
return apimodel.HandlerWithOptions(h, apimodel.ChiServerOptions{
|
2024-02-10 10:53:14 +00:00
|
|
|
BaseRouter: r,
|
|
|
|
Middlewares: []apimodel.MiddlewareFunc{
|
|
|
|
middleware.NoCache,
|
|
|
|
h.versionMiddleware,
|
|
|
|
h.serverMiddleware,
|
2024-02-20 07:14:35 +00:00
|
|
|
h.tribeMiddleware,
|
2024-02-29 06:25:01 +00:00
|
|
|
h.playerMiddleware,
|
2024-03-07 05:52:03 +00:00
|
|
|
h.villageMiddleware,
|
2024-02-10 10:53:14 +00:00
|
|
|
},
|
2024-01-31 07:14:18 +00:00
|
|
|
ErrorHandlerFunc: func(w http.ResponseWriter, r *http.Request, err error) {
|
2024-02-23 06:51:37 +00:00
|
|
|
h.errorRenderer.render(w, r, err)
|
2024-01-31 07:14:18 +00:00
|
|
|
},
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (h *apiHTTPHandler) handleNotFound(w http.ResponseWriter, r *http.Request) {
|
2024-02-23 06:51:37 +00:00
|
|
|
h.errorRenderer.render(w, r, apiError{
|
|
|
|
status: http.StatusNotFound,
|
|
|
|
code: "route-not-found",
|
|
|
|
message: "route not found",
|
|
|
|
})
|
2024-01-23 07:13:55 +00:00
|
|
|
}
|
|
|
|
|
2024-01-31 07:14:18 +00:00
|
|
|
func (h *apiHTTPHandler) handleMethodNotAllowed(w http.ResponseWriter, r *http.Request) {
|
2024-02-23 06:51:37 +00:00
|
|
|
h.errorRenderer.render(w, r, apiError{
|
|
|
|
status: http.StatusMethodNotAllowed,
|
|
|
|
code: "method-not-allowed",
|
|
|
|
message: "method not allowed",
|
|
|
|
})
|
2024-01-23 07:13:55 +00:00
|
|
|
}
|