Skip to content

Instantly share code, notes, and snippets.

@JoshuaSchlichting
Created December 13, 2022 00:28
Show Gist options
  • Save JoshuaSchlichting/8bce5a4c3fa7d293fd4c88660dff495d to your computer and use it in GitHub Desktop.
Save JoshuaSchlichting/8bce5a4c3fa7d293fd4c88660dff495d to your computer and use it in GitHub Desktop.
A basic HTTP router
package router
import (
"encoding/json"
"html/template"
"io/fs"
"net/http"
)
var commonMiddleware = []Middleware{}
type Router struct {
*http.ServeMux
StaticFileSystem fs.FS
Template *template.Template
}
func NewRouter(staticFileSystem fs.FS, template *template.Template) *Router {
mux := http.NewServeMux()
subFolderStaticFileSystem, err := fs.Sub(staticFileSystem, "static")
if err != nil {
panic(err)
}
// serve static files
mux.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.FS(subFolderStaticFileSystem))))
return &Router{
ServeMux: mux,
StaticFileSystem: staticFileSystem,
Template: template,
}
}
func (r *Router) GET(path string, handler http.HandlerFunc) {
// loop over common middleware reverse order
for i := len(commonMiddleware) - 1; i >= 0; i-- {
handler = commonMiddleware[i](handler).ServeHTTP
}
r.HandleFunc(path, func(w http.ResponseWriter, req *http.Request) {
if req.Method != http.MethodGet {
http.NotFound(w, req)
return
}
handler(w, req)
})
}
func (r *Router) POST(path string, handler http.HandlerFunc) {
r.HandleFunc(path, func(w http.ResponseWriter, req *http.Request) {
if req.Method != http.MethodPost {
http.NotFound(w, req)
return
}
handler(w, req)
})
}
func (r *Router) JSON(w http.ResponseWriter, data interface{}, code int) {
buf, err := json.Marshal(data)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
status := http.StatusOK
if code != 0 {
status = code
}
w.WriteHeader(status)
w.Write(buf)
}
type Middleware func(http.Handler) http.Handler
// Use adds middleware to the router. You can list multiple middleware here,
// or make multiple calls. Middleware is applied in the order it is added.
func (r *Router) Use(middleware ...Middleware) {
commonMiddleware = append(commonMiddleware, middleware...)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment