Skip to content

Commit

Permalink
refactor middleware api
Browse files Browse the repository at this point in the history
  • Loading branch information
zrcoder committed Dec 26, 2024
1 parent b8bbbbb commit ec67e71
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 46 deletions.
49 changes: 15 additions & 34 deletions amis.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,60 +4,56 @@ package amisgo
import (
"net/http"
"strings"
"sync"

"github.com/zrcoder/amisgo/conf"
"github.com/zrcoder/amisgo/internal/servermux"
"github.com/zrcoder/amisgo/util"
)

// Engine represents the web application
type Engine struct {
Config *conf.Config
mux *http.ServeMux
middlewares []func(http.Handler) http.Handler
handler http.Handler
handlerOnce sync.Once
Config *conf.Config
mux *http.ServeMux
}

// New creates an Engine instance with options
func New(opts ...conf.Option) *Engine {
cfg := conf.Default()
cfg.Apply(opts...)

e := &Engine{
return &Engine{
Config: cfg,
mux: servermux.Mux(),
}

return e
}

// Mount registers an Amis component at the given path
func (e *Engine) Mount(path string, component any) *Engine {
e.mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
func (e *Engine) Mount(path string, component any, middlewares ...func(http.Handler) http.Handler) *Engine {
var h http.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
e.renderComponent(w, component)
})
h = util.WithMiddlewares(h, middlewares...)
e.mux.Handle(path, h)
return e
}

// Redirect sets up a URL redirection
func (e *Engine) Redirect(src, dst string) *Engine {
func (e *Engine) Redirect(src, dst string, code int) *Engine {
e.mux.HandleFunc(src, func(w http.ResponseWriter, r *http.Request) {
Redirect(w, r, dst, http.StatusPermanentRedirect)
util.Redirect(w, r, dst, code)
})
return e
}

// Handle registers a handler at the given path
func (e *Engine) Handle(path string, handler http.Handler) *Engine {
e.mux.Handle(path, handler)
func (e *Engine) Handle(path string, handler http.Handler, middlewares ...func(http.Handler) http.Handler) *Engine {
e.mux.Handle(path, util.WithMiddlewares(handler, middlewares...))
return e
}

// HandleFunc registers a handler function at the given path
func (e *Engine) HandleFunc(path string, handler func(http.ResponseWriter, *http.Request)) *Engine {
e.mux.HandleFunc(path, handler)
return e
func (e *Engine) HandleFunc(path string, handler http.HandlerFunc, middlewares ...func(http.Handler) http.Handler) *Engine {
return e.Handle(path, handler, middlewares...)
}

// StaticFS registers a file server for serving static files
Expand All @@ -76,12 +72,6 @@ func (e *Engine) StaticFiles(prefix string, root string) *Engine {
return e.StaticFS(prefix, http.Dir(root))
}

// Use adds a middleware function to the engine for processing requests
func (e *Engine) Use(middleware func(http.Handler) http.Handler) *Engine {
e.middlewares = append(e.middlewares, middleware)
return e
}

// Run starts the HTTP server
func (e *Engine) Run(addr ...string) error {
address := ":80"
Expand All @@ -94,16 +84,7 @@ func (e *Engine) Run(addr ...string) error {

// ServeHTTP implements http.Handler interface
func (e *Engine) ServeHTTP(w http.ResponseWriter, r *http.Request) {
e.handlerOnce.Do(func() {
e.handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
e.mux.ServeHTTP(w, r)
})
for _, m := range e.middlewares {
e.handler = m(e.handler)
}
})

e.handler.ServeHTTP(w, r)
e.mux.ServeHTTP(w, r)
}

// renderComponent renders an Amis component
Expand Down
6 changes: 2 additions & 4 deletions amis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ func TestMount(t *testing.T) {

func TestRedirect(t *testing.T) {
e := New()
e.Redirect("/old", "/new")
e.Redirect("/old", "/new", http.StatusPermanentRedirect)

w := httptest.NewRecorder()
r := httptest.NewRequest("GET", "/old", nil)
Expand Down Expand Up @@ -209,11 +209,9 @@ func TestUse(t *testing.T) {
})
}

e.Use(middleware)

e.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello, World!"))
})
}, middleware)

w := httptest.NewRecorder()
r := httptest.NewRequest("GET", "/test", nil)
Expand Down
8 changes: 0 additions & 8 deletions util.go

This file was deleted.

16 changes: 16 additions & 0 deletions util/util.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package util

import "net/http"

// Redirect is a utility function to perform an HTTP redirect.
func Redirect(w http.ResponseWriter, r *http.Request, url string, code int) {
http.Redirect(w, r, url, code)
}

// WithMiddlewares applies a chain of middleware functions to an HTTP handler.
func WithMiddlewares(h http.Handler, middlewares ...func(http.Handler) http.Handler) http.Handler {
for i := len(middlewares) - 1; i >= 0; i-- {
h = middlewares[i](h)
}
return h
}

0 comments on commit ec67e71

Please sign in to comment.