Minimalistic Go http router based on Mat Ryer's way
It differs from way by adding the path parameters to the form values. To retrieve them, use the rue.Param function :
value := rue.Param(req, parameter)
For example, with the url pattern /path/:param1 :
value := rue.Param(req,"param1")
You can also retrieve all form values in the same manner.
Multiple values are concatenate with the semi-colon separator. For example, for the url query /path?m=a&m=b&m=c :
result := rue.Param(req, "m")
fmt.Println(result) // a;b;c
The request FQDN (without port) and host prefix are also added to the form values with respectively the _fqdn and the _host key. For example, for a complete url like https://something.domain.tld/query :
f := rue.Param(req, "_fqdn")
fmt.Printf("The FQDN is %s", f) // The FQDN is something.domain.tld
h := rue.Param(req, "_host")
fmt.Printf("The host is %s", h) // The host is something
Finally, you can also specify a static file folder to be served by the router :
router := rue.NewRouter()
router.HandleStatic("/", "./static/")
panic(http.ListenAndServe(":8080", router))
Important rule : the static handler must be the last added handler to the router.
A minimal hello world handler with a name as path parameter :
package main
import (
"net/http"
"github.com/sipkg/rue"
)
func main() {
// create the router
router := rue.NewRouter()
// add the handler functions with the method and the parameter path
router.HandleFunc("GET", "hello/:name",
func(w http.ResponseWriter, r *http.Request) {
message := "Hello " + rue.Param(r, "name")
w.Write([]byte(message))
})
println("listening on port 8080...")
panic(http.ListenAndServe(":8080", router))
}
A more complicated example with mixed origins.
package main
import (
"net/http"
"github.com/sipkg/rue"
)
func main() {
router := rue.NewRouter()
router.HandleFunc("POST", "/path/:para1/:para2", handle)
println("Listening on port 8080...")
panic(http.ListenAndServe(":8080", router))
}
func handle(w http.ResponseWriter, r *http.Request) {
params := []string{"para1", "para2", "multi", "post", "get", "_host"}
data := ""
for _, p := range params {
data = data + p + ": \t" + rue.Param(r, p) + "\n"
}
w.Write([]byte(data))
}
Simulate an http POST with :
curl --data 'post=foo&multi=one' http://host.localhost:8080/path/foo/bar\?get=\bar\&multi\=two\&multi\=three
Reminder : Don't forget to inialize the go modules before running this examples. Someting like :
go mod init rue_example && go mod tidy && go run .
- Use
NewRouter
to make a newRouter
- Call
Handle
andHandleFunc
to add handlers. - Call
HandleStatic
to add a file system handler. - Specify HTTP method and path pattern for each route.
- Use
Param
function to get the parameters value from the context. - Use
Params
function to get the list of all used parameters names (including special parameters _fqdn and _host).
func main() {
router := rue.NewRouter()
router.HandleFunc("GET", "/music/:band/:song", handleReadSong)
router.HandleFunc("PUT", "/music/:band/:song", handleUpdateSong)
router.HandleFunc("DELETE", "/music/:band/:song", handleDeleteSong)
router.HandleStatic("/", "./static")
panic(http.ListenAndServe(":8080", router))
}
func handleReadSong(w http.ResponseWriter, r *http.Request) {
band := rue.Param(r, "band")
song := rue.Param(r, "song")
// use 'band' and 'song' parameters...
}
- Prefix matching
To match any path that has a specific prefix, use the ...
prefix indicator:
router := rue.NewRouter()
router.HandleFunc("GET", "/images...", handleImages)
/* In the above example, the following paths will match:
- `/images`
- `/images/`
- `/images/one/two/three.jpg`
*/
- Set
Router.NotFound
to handle 404 errors manually
func main() {
router := rue.NewRouter()
router.NotFound = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNotFound)
fmt.Fprintf(w, "This is not the page you are looking for")
})
panic(http.ListenAndServe(":8080", router))
}