85 lines
2.2 KiB
Go
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)
|
|
}
|