go-tower: first release v0.1.0

This commit is contained in:
2026-02-14 14:02:21 +00:00
parent 93a16c3665
commit 3576d420d2
13 changed files with 753 additions and 1 deletions

117
tower.go Normal file
View File

@@ -0,0 +1,117 @@
package tower
import (
"context"
"log"
"net/http"
"github.com/julienschmidt/httprouter"
)
type Tower struct {
router *httprouter.Router
errorHandler ErrorHandler
globalMiddlewares []Middleware
server *http.Server
}
func New() *Tower {
t := &Tower{
router: httprouter.New(),
errorHandler: defaultErrorHandler,
globalMiddlewares: []Middleware{},
}
t.server = &http.Server{
Handler: t.router,
}
return t
}
func (t *Tower) Start(listenAddr string) error {
t.server.Addr = listenAddr
return t.server.ListenAndServe()
}
func (t *Tower) StartTLS(listenAddr, certFile, keyFile string) error {
t.server.Addr = listenAddr
return t.server.ListenAndServeTLS(certFile, keyFile)
}
func (t *Tower) Shutdown(ctx context.Context) error {
return t.server.Shutdown(ctx)
}
func (t *Tower) SetErrorHandler(errorHandler ErrorHandler) {
t.errorHandler = errorHandler
}
func (t *Tower) Use(globalMiddlewares ...Middleware) {
t.globalMiddlewares = append(t.globalMiddlewares, globalMiddlewares...)
}
func (t *Tower) Group(prefix string, groupMiddlewares ...Middleware) *Group {
return &Group{
prefix: normalizePath(prefix),
parent: t,
groupMiddlewares: groupMiddlewares,
}
}
func (t *Tower) Static(prefix, dir string) {
prefix = normalizePath(prefix)
prefix += "/*filepath"
t.router.ServeFiles(prefix, http.Dir(dir))
}
func (t *Tower) GET(path string, h Handler, routeMiddlewares ...Middleware) {
t.Handle(http.MethodGet, path, h, routeMiddlewares...)
}
func (t *Tower) POST(path string, h Handler, routeMiddlewares ...Middleware) {
t.Handle(http.MethodPost, path, h, routeMiddlewares...)
}
func (t *Tower) PUT(path string, h Handler, routeMiddlewares ...Middleware) {
t.Handle(http.MethodPut, path, h, routeMiddlewares...)
}
func (t *Tower) PATCH(path string, h Handler, routeMiddlewares ...Middleware) {
t.Handle(http.MethodPatch, path, h, routeMiddlewares...)
}
func (t *Tower) DELETE(path string, h Handler, routeMiddlewares ...Middleware) {
t.Handle(http.MethodDelete, path, h, routeMiddlewares...)
}
func (t *Tower) Handle(method string, path string, h Handler, routeMiddlewares ...Middleware) {
t.router.Handle(method, path, t.buildHTTPRouterHandle(h, routeMiddlewares...))
}
func (t *Tower) buildHTTPRouterHandle(h Handler, routeMiddlewares ...Middleware) httprouter.Handle {
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
ctx := Context{
request: r,
response: &responseWriter{ResponseWriter: w},
params: p,
}
wrappedHandler := h
for i := len(routeMiddlewares) - 1; i >= 0; i-- {
wrappedHandler = routeMiddlewares[i](wrappedHandler)
}
for i := len(t.globalMiddlewares) - 1; i >= 0; i-- {
wrappedHandler = t.globalMiddlewares[i](wrappedHandler)
}
if err := wrappedHandler(&ctx); err != nil {
if err := t.errorHandler(&ctx, err); err != nil {
log.Printf("[Error] %v", err)
}
}
}
}