Skip to content

Instantly share code, notes, and snippets.

@oludouglas
Created September 15, 2020 13:02
Show Gist options
  • Save oludouglas/e6bff79e81a9e34cf06a2c362d955300 to your computer and use it in GitHub Desktop.
Save oludouglas/e6bff79e81a9e34cf06a2c362d955300 to your computer and use it in GitHub Desktop.
package main
// demonstrates how to create a simple http router compartible with std net/http lib
import (
"net/http"
"strings"
)
type Handle func(http.ResponseWriter, *http.Request)
type Router struct {
handler map[string]Handle
}
func NewRouter() *Router {
r := new(Router)
r.handler = make(map[string]Handle)
return r
}
func (r *Router) Get(path string, h Handle) {
r.Handle(http.MethodGet, path, h)
}
func (r *Router) Post(path string, h Handle) {
r.Handle(http.MethodPost, path, h)
}
func (r *Router) Put(path string, h Handle) {
r.Handle(http.MethodPut, path, h)
}
func key(method, path string) string {
return method + ":" + path
}
//ServeHTTP handles all connections from http clients
func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) {
fn, ok := r.handler[key(req.Method, req.URL.Path)]
if !ok {
// do something here like say invalid url path
w.Write([]byte("Invalid URL Context path specified"))
return
}
fn(w, req)
}
func (r *Router) Handle(method, path string, handle Handle) {
if method == "" {
panic("method must not be empty")
}
if len(path) < 1 || path[0] != '/' {
panic("method must begin with a forward slash /")
}
if handle == nil {
panic("handle must not be nil")
}
r.handler[key(method, path)] = handle
}
func main() {
// Usage is simple as below.
// This does not cater for param slicing and shouldn't be used for production.
router := NewRouter()
router.Get("/users", func(w http.ResponseWriter, r *http.Request) {
// do whatever you want with the request/response
w.Write([]byte("This is a list of get items"))
})
router.Get("/users/:name", func(w http.ResponseWriter, r *http.Request) {
// do whatever you want with the request/response
name := strings.TrimPrefix(r.URL.Path, "/users/")
w.Write([]byte("This is your " + name))
})
router.Post("/users", func(w http.ResponseWriter, r *http.Request) {
// do whatever you want with the request/response
panic("implement me")
})
http.ListenAndServe(":3000", router)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment