Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 27 additions & 34 deletions chirouter/wrapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/go-chi/chi/v5"
"github.com/swaggest/rest"
"github.com/swaggest/rest/nethttp"
"github.com/swaggest/usecase"
)

// NewWrapper creates router wrapper to upgrade middlewares processing.
Expand All @@ -29,8 +30,6 @@ type Wrapper struct {
handlers []http.Handler
}

var _ chi.Router = &Wrapper{}

func (r *Wrapper) copy(router chi.Router, pattern string) *Wrapper {
return &Wrapper{
Router: router,
Expand Down Expand Up @@ -68,7 +67,7 @@ func (r *Wrapper) Use(middlewares ...func(http.Handler) http.Handler) {
}

// With adds inline middlewares for an endpoint handler.
func (r Wrapper) With(middlewares ...func(http.Handler) http.Handler) chi.Router {
func (r Wrapper) With(middlewares ...func(http.Handler) http.Handler) *Wrapper {
var mws, ws []func(http.Handler) http.Handler

for _, mw := range middlewares {
Expand All @@ -86,7 +85,7 @@ func (r Wrapper) With(middlewares ...func(http.Handler) http.Handler) chi.Router
}

// Group adds a new inline-router along the current routing path, with a fresh middleware stack for the inline-router.
func (r *Wrapper) Group(fn func(r chi.Router)) chi.Router {
func (r *Wrapper) Group(fn func(r *Wrapper)) *Wrapper {
im := r.With()

if fn != nil {
Expand All @@ -97,7 +96,7 @@ func (r *Wrapper) Group(fn func(r chi.Router)) chi.Router {
}

// Route mounts a sub-router along a `basePattern` string.
func (r *Wrapper) Route(pattern string, fn func(r chi.Router)) chi.Router {
func (r *Wrapper) Route(pattern string, fn func(r *Wrapper)) *Wrapper {
subRouter := r.copy(chi.NewRouter(), pattern)

if fn != nil {
Expand Down Expand Up @@ -154,49 +153,43 @@ func (r *Wrapper) MethodFunc(method, pattern string, handlerFn http.HandlerFunc)
r.Method(method, pattern, handlerFn)
}

// Connect adds the route `pattern` that matches a CONNECT http method to execute the `handlerFn` http.HandlerFunc.
func (r *Wrapper) Connect(pattern string, handlerFn http.HandlerFunc) {
r.Method(http.MethodConnect, pattern, handlerFn)
}

// Delete adds the route `pattern` that matches a DELETE http method to execute the `handlerFn` http.HandlerFunc.
func (r *Wrapper) Delete(pattern string, handlerFn http.HandlerFunc) {
r.Method(http.MethodDelete, pattern, handlerFn)
func (r *Wrapper) Delete(pattern string, uc usecase.Interactor, options ...func(h *nethttp.Handler)) {
r.Method(http.MethodDelete, pattern, nethttp.NewHandler(uc, options...))
}

// Get adds the route `pattern` that matches a GET http method to execute the `handlerFn` http.HandlerFunc.
func (r *Wrapper) Get(pattern string, handlerFn http.HandlerFunc) {
r.Method(http.MethodGet, pattern, handlerFn)
// Get adds the route `pattern` that matches a GET http method to invoke use case interactor.
func (r *Wrapper) Get(pattern string, uc usecase.Interactor, options ...func(h *nethttp.Handler)) {
r.Method(http.MethodGet, pattern, nethttp.NewHandler(uc, options...))
}

// Head adds the route `pattern` that matches a HEAD http method to execute the `handlerFn` http.HandlerFunc.
func (r *Wrapper) Head(pattern string, handlerFn http.HandlerFunc) {
r.Method(http.MethodHead, pattern, handlerFn)
// Head adds the route `pattern` that matches a HEAD http method to invoke use case interactor.
func (r *Wrapper) Head(pattern string, uc usecase.Interactor, options ...func(h *nethttp.Handler)) {
r.Method(http.MethodHead, pattern, nethttp.NewHandler(uc, options...))
}

// Options adds the route `pattern` that matches a OPTIONS http method to execute the `handlerFn` http.HandlerFunc.
func (r *Wrapper) Options(pattern string, handlerFn http.HandlerFunc) {
r.Method(http.MethodOptions, pattern, handlerFn)
// Options adds the route `pattern` that matches a OPTIONS http method to invoke use case interactor.
func (r *Wrapper) Options(pattern string, uc usecase.Interactor, options ...func(h *nethttp.Handler)) {
r.Method(http.MethodOptions, pattern, nethttp.NewHandler(uc, options...))
}

// Patch adds the route `pattern` that matches a PATCH http method to execute the `handlerFn` http.HandlerFunc.
func (r *Wrapper) Patch(pattern string, handlerFn http.HandlerFunc) {
r.Method(http.MethodPatch, pattern, handlerFn)
// Patch adds the route `pattern` that matches a PATCH http method to invoke use case interactor.
func (r *Wrapper) Patch(pattern string, uc usecase.Interactor, options ...func(h *nethttp.Handler)) {
r.Method(http.MethodPatch, pattern, nethttp.NewHandler(uc, options...))
}

// Post adds the route `pattern` that matches a POST http method to execute the `handlerFn` http.HandlerFunc.
func (r *Wrapper) Post(pattern string, handlerFn http.HandlerFunc) {
r.Method(http.MethodPost, pattern, handlerFn)
// Post adds the route `pattern` that matches a POST http method to invoke use case interactor.
func (r *Wrapper) Post(pattern string, uc usecase.Interactor, options ...func(h *nethttp.Handler)) {
r.Method(http.MethodPost, pattern, nethttp.NewHandler(uc, options...))
}

// Put adds the route `pattern` that matches a PUT http method to execute the `handlerFn` http.HandlerFunc.
func (r *Wrapper) Put(pattern string, handlerFn http.HandlerFunc) {
r.Method(http.MethodPut, pattern, handlerFn)
// Put adds the route `pattern` that matches a PUT http method to invoke use case interactor.
func (r *Wrapper) Put(pattern string, uc usecase.Interactor, options ...func(h *nethttp.Handler)) {
r.Method(http.MethodPut, pattern, nethttp.NewHandler(uc, options...))
}

// Trace adds the route `pattern` that matches a TRACE http method to execute the `handlerFn` http.HandlerFunc.
func (r *Wrapper) Trace(pattern string, handlerFn http.HandlerFunc) {
r.Method(http.MethodTrace, pattern, handlerFn)
// Trace adds the route `pattern` that matches a TRACE http method to invoke use case interactor.
func (r *Wrapper) Trace(pattern string, uc usecase.Interactor, options ...func(h *nethttp.Handler)) {
r.Method(http.MethodTrace, pattern, nethttp.NewHandler(uc, options...))
}

func (r *Wrapper) resolvePattern(pattern string) string {
Expand Down
59 changes: 29 additions & 30 deletions chirouter/wrapper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"errors"
"net/http"
"net/http/httptest"
"net/url"
"testing"

"github.com/go-chi/chi/v5"
Expand Down Expand Up @@ -78,40 +77,40 @@ func TestNewWrapper(t *testing.T) {

r.Use(mw)

r.Group(func(r chi.Router) {
r.Method(http.MethodPost,
"/baz/{id}/",
HandlerWithFoo{Handler: http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
val, err := chirouter.PathToURLValues(request)
assert.NoError(t, err)
assert.Equal(t, url.Values{"id": []string{"123"}}, val)
})},
)
})
// r.Group(func(r chi.Router) {
// r.Method(http.MethodPost,
// "/baz/{id}/",
// HandlerWithFoo{Handler: http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
// val, err := chirouter.PathToURLValues(request)
// assert.NoError(t, err)
// assert.Equal(t, url.Values{"id": []string{"123"}}, val)
// })},
// )
// })

r.Mount("/mount",
HandlerWithFoo{Handler: http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {})},
)

r.Route("/deeper", func(r chi.Router) {
r.Use(func(handler http.Handler) http.Handler {
return HandlerWithFoo{Handler: handler}
})

r.Get("/foo", func(writer http.ResponseWriter, request *http.Request) {})
r.Head("/foo", func(writer http.ResponseWriter, request *http.Request) {})
r.Post("/foo", func(writer http.ResponseWriter, request *http.Request) {})
r.Put("/foo", func(writer http.ResponseWriter, request *http.Request) {})
r.Trace("/foo", func(writer http.ResponseWriter, request *http.Request) {})
r.Connect("/foo", func(writer http.ResponseWriter, request *http.Request) {})
r.Options("/foo", func(writer http.ResponseWriter, request *http.Request) {})
r.Patch("/foo", func(writer http.ResponseWriter, request *http.Request) {})
r.Delete("/foo", func(writer http.ResponseWriter, request *http.Request) {})

r.MethodFunc(http.MethodGet, "/cuux", func(writer http.ResponseWriter, request *http.Request) {})

r.Handle("/bar", http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {}))
})
// r.Route("/deeper", func(r chi.Router) {
// r.Use(func(handler http.Handler) http.Handler {
// return HandlerWithFoo{Handler: handler}
// })

// r.Get("/foo", func(writer http.ResponseWriter, request *http.Request) {})
// r.Head("/foo", func(writer http.ResponseWriter, request *http.Request) {})
// r.Post("/foo", func(writer http.ResponseWriter, request *http.Request) {})
// r.Put("/foo", func(writer http.ResponseWriter, request *http.Request) {})
// r.Trace("/foo", func(writer http.ResponseWriter, request *http.Request) {})
// r.Connect("/foo", func(writer http.ResponseWriter, request *http.Request) {})
// r.Options("/foo", func(writer http.ResponseWriter, request *http.Request) {})
// r.Patch("/foo", func(writer http.ResponseWriter, request *http.Request) {})
// r.Delete("/foo", func(writer http.ResponseWriter, request *http.Request) {})

// r.MethodFunc(http.MethodGet, "/cuux", func(writer http.ResponseWriter, request *http.Request) {})

// r.Handle("/bar", http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {}))
// })

for _, u := range []string{"/baz/123/", "/deeper/foo", "/mount/abc"} {
req, err := http.NewRequest(http.MethodPost, u, nil)
Expand Down
41 changes: 0 additions & 41 deletions web/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import (
"github.com/swaggest/rest/openapi"
"github.com/swaggest/rest/request"
"github.com/swaggest/rest/response"
"github.com/swaggest/usecase"
)

// DefaultService initializes router and other basic components of web service.
Expand Down Expand Up @@ -93,46 +92,6 @@ type Service struct {
ResponseValidatorFactory rest.ResponseValidatorFactory
}

// Delete adds the route `pattern` that matches a DELETE http method to invoke use case interactor.
func (s *Service) Delete(pattern string, uc usecase.Interactor, options ...func(h *nethttp.Handler)) {
s.Method(http.MethodDelete, pattern, nethttp.NewHandler(uc, options...))
}

// Get adds the route `pattern` that matches a GET http method to invoke use case interactor.
func (s *Service) Get(pattern string, uc usecase.Interactor, options ...func(h *nethttp.Handler)) {
s.Method(http.MethodGet, pattern, nethttp.NewHandler(uc, options...))
}

// Head adds the route `pattern` that matches a HEAD http method to invoke use case interactor.
func (s *Service) Head(pattern string, uc usecase.Interactor, options ...func(h *nethttp.Handler)) {
s.Method(http.MethodHead, pattern, nethttp.NewHandler(uc, options...))
}

// Options adds the route `pattern` that matches a OPTIONS http method to invoke use case interactor.
func (s *Service) Options(pattern string, uc usecase.Interactor, options ...func(h *nethttp.Handler)) {
s.Method(http.MethodOptions, pattern, nethttp.NewHandler(uc, options...))
}

// Patch adds the route `pattern` that matches a PATCH http method to invoke use case interactor.
func (s *Service) Patch(pattern string, uc usecase.Interactor, options ...func(h *nethttp.Handler)) {
s.Method(http.MethodPatch, pattern, nethttp.NewHandler(uc, options...))
}

// Post adds the route `pattern` that matches a POST http method to invoke use case interactor.
func (s *Service) Post(pattern string, uc usecase.Interactor, options ...func(h *nethttp.Handler)) {
s.Method(http.MethodPost, pattern, nethttp.NewHandler(uc, options...))
}

// Put adds the route `pattern` that matches a PUT http method to invoke use case interactor.
func (s *Service) Put(pattern string, uc usecase.Interactor, options ...func(h *nethttp.Handler)) {
s.Method(http.MethodPut, pattern, nethttp.NewHandler(uc, options...))
}

// Trace adds the route `pattern` that matches a TRACE http method to invoke use case interactor.
func (s *Service) Trace(pattern string, uc usecase.Interactor, options ...func(h *nethttp.Handler)) {
s.Method(http.MethodTrace, pattern, nethttp.NewHandler(uc, options...))
}

// Docs adds the route `pattern` that serves API documentation with Swagger UI.
//
// Swagger UI should be provided by `swgui` handler constructor, you can use one of these functions
Expand Down