fiber_docs/router/router.go

161 lines
3.5 KiB
Go

package router
import (
"container/list"
"reflect"
"git.ma-al.com/goc_marek/fiber_docs/security"
"github.com/go-playground/validator/v10"
"github.com/gofiber/fiber/v2"
"github.com/jinzhu/copier"
"github.com/mcuadros/go-defaults"
)
type Model any
type Router struct {
Handlers *list.List
Path string
Method string
Summary string
Description string
Deprecated bool
RequestContentType string
ResponseContentType string
Tags []string
API fiber.Handler
Model Model
OperationID string
Exclude bool
Securities []security.ISecurity
Response Response
}
var validate = validator.New()
func BindModel(req interface{}) fiber.Handler {
return func(c *fiber.Ctx) error {
model := reflect.New(reflect.TypeOf(req).Elem()).Interface()
if err := HeaderParser(c, model); err != nil {
return err
}
if err := CookiesParser(c, model); err != nil {
return err
}
if err := c.QueryParser(model); err != nil {
return err
}
if c.Method() == fiber.MethodPost || c.Method() == fiber.MethodPut {
if err := c.BodyParser(model); err != nil {
return err
}
}
if err := ParamsParser(c, model); err != nil {
return err
}
defaults.SetDefaults(model)
if err := validate.Struct(model); err != nil {
return err
}
if err := copier.Copy(req, model); err != nil {
return err
}
return c.Next()
}
}
func (router *Router) GetHandlers() []fiber.Handler {
var handlers []fiber.Handler
for _, s := range router.Securities {
handlers = append(handlers, s.Authorize)
}
for h := router.Handlers.Front(); h != nil; h = h.Next() {
if f, ok := h.Value.(fiber.Handler); ok {
handlers = append(handlers, f)
}
}
handlers = append(handlers, router.API)
return handlers
}
func NewX(f fiber.Handler, options ...Option) *Router {
r := &Router{
Handlers: list.New(),
Response: make(Response),
API: func(ctx *fiber.Ctx) error {
return f(ctx)
},
}
for _, option := range options {
option(r)
}
return r
}
func New[T Model, F func(c *fiber.Ctx, req T) error](f F, options ...Option) *Router {
var model T
h := BindModel(&model)
r := &Router{
Handlers: list.New(),
Response: make(Response),
API: func(ctx *fiber.Ctx) error {
return f(ctx, model)
},
Model: model,
}
for _, option := range options {
option(r)
}
r.Handlers.PushBack(h)
return r
}
func (router *Router) WithSecurity(securities ...security.ISecurity) *Router {
Security(securities...)(router)
return router
}
func (router *Router) WithResponses(response Response) *Router {
Responses(response)(router)
return router
}
func (router *Router) WithHandlers(handlers ...fiber.Handler) *Router {
Handlers(handlers...)(router)
return router
}
func (router *Router) WithTags(tags ...string) *Router {
Tags(tags...)(router)
return router
}
func (router *Router) WithSummary(summary string) *Router {
Summary(summary)(router)
return router
}
func (router *Router) WithDescription(description string) *Router {
Description(description)(router)
return router
}
func (router *Router) WithDeprecated() *Router {
Deprecated()(router)
return router
}
func (router *Router) WithOperationID(ID string) *Router {
OperationID(ID)(router)
return router
}
func (router *Router) WithExclude() *Router {
Exclude()(router)
return router
}
func (router *Router) WithContentType(contentType string, contentTypeType ContentTypeType) *Router {
ContentType(contentType, contentTypeType)(router)
return router
}