vinegar/servlet/dynamicRoute.go
2023-08-01 13:34:08 -04:00

85 lines
2.2 KiB
Go

package servlet
import (
"fmt"
"log"
"net/http"
)
type (
//ApiRoute provides a way to define API routes that handle multiple HTTP methods.
//
//It contains:
//
//VinegarRoute - The base VinegarWebRoute that defines the URL pattern to match.
//
//HttpMethodRoutes - A pointer to a map of HTTP method string to handler function.
//
//Usage:
//
//1. Create a new ApiRoute, providing a VinegarHttpServlet and URL pattern:
//
// route := NewApiRoute(serv, "/api/users")
//
//2. Add handler functions for each supported HTTP method:
//
// route.RegisterHttpMethodHandler(http.MethodGet, handleGet)
// route.RegisterHttpMethodHandler(http.MethodPost, handlePost)
//
//3. The route will now match the pattern "/api/users" and call the right
// handler function based on the HTTP method used in the request.
//
//4. If an unsupported HTTP method is used, a 404 error will be returned.
ApiRoute struct {
VinegarRoute *VinegarWebRoute
HttpMethodRoutes *map[string]VinegarHandlerFunction
}
)
//NewApiRoute this will cause a panic if serv is nil
func NewApiRoute(serv *VinegarWebServlet, pattern string) *ApiRoute {
functionMap := make(map[string]VinegarHandlerFunction)
ancestorRoute := NewServletRoute(pattern, createMethodHandler(&functionMap))
route := ApiRoute{
ancestorRoute,
&functionMap,
}
if serv != nil { //this will happen during testing
serv.Router.AddRoute(route.VinegarRoute)
}
return &route
}
func createMethodHandler(m *map[string]VinegarHandlerFunction) VinegarHandlerFunction {
return func(w http.ResponseWriter, req *http.Request) {
fn, exists := (*m)[req.Method]
if exists {
fn(w, req)
} else {
http.NotFound(w, req)
}
}
}
func (api *ApiRoute) RegisterHttpMethodHandler(method string, handler VinegarHandlerFunction) {
(*api.HttpMethodRoutes)[method] = handler
}
func (api *ApiRoute) AddGetHandler(handler VinegarHandlerFunction) {
(*api.HttpMethodRoutes)[http.MethodGet] = handler
}
func SendApiError(w http.ResponseWriter, httpCode int, messageCode int, message string) {
respMessage := fmt.Sprintf("{\"code\":%d, \"message\":\"%s\"}", messageCode, message)
log.Printf("[ERROR]\t%s\n", respMessage)
_, err := w.Write([]byte(respMessage))
if err != nil {
log.Println(err)
}
w.WriteHeader(httpCode)
}