package server import ( "io" "log" "net/http" "git.akyoto.dev/go/router" ) // Handler is a function that deals with the given request/response context. type Handler func(Context) error // Server represents a single web service. type Server struct { router *router.Router[Handler] } // New creates a new server. func New() *Server { return &Server{ router: router.New[Handler](), } } // Get registers your function to be called when the given GET path has been requested. func (server *Server) Get(path string, handler Handler) { server.router.Add(http.MethodGet, path, handler) } // Post registers your function to be called when the given POST path has been requested. func (server *Server) Post(path string, handler Handler) { server.router.Add(http.MethodPost, path, handler) } // Delete registers your function to be called when the given DELETE path has been requested. func (server *Server) Delete(path string, handler Handler) { server.router.Add(http.MethodDelete, path, handler) } // Put registers your function to be called when the given PUT path has been requested. func (server *Server) Put(path string, handler Handler) { server.router.Add(http.MethodPut, path, handler) } // ServeHTTP responds to the given request. func (server *Server) ServeHTTP(response http.ResponseWriter, request *http.Request) { ctx := newContext(request, response) handler := server.router.LookupNoAlloc(request.Method, request.URL.Path, ctx.addParameter) if handler == nil { response.WriteHeader(http.StatusNotFound) response.(io.StringWriter).WriteString(http.StatusText(http.StatusNotFound)) contextPool.Put(ctx) return } err := handler(ctx) if err != nil { response.(io.StringWriter).WriteString(err.Error()) log.Println(request.URL, err) } contextPool.Put(ctx) }