In Restful services, we may expect to achieve such requirements.
- The interface path is the same, but according to different request methods, different processing requests are performed
- Forward requests for a certain path to another host
- Handle https and http requests to different
handler
processes - Match different sub-routes according to the path prefix and forward them to different
handler
processing
gorilla/mux
These requirements can be fulfilled by powerful
1. Routing according to different request methods
package main
import (
"fmt"
"net/http"
"github.com/gorilla/mux"
)
func main() {
r := mux.NewRouter()
r.HandleFunc("/books/{title}", CreateBook).Methods("POST")
r.HandleFunc("/books/{title}", ReadBook).Methods("GET")
r.HandleFunc("/books/{title}", UpdateBook).Methods("PUT")
r.HandleFunc("/books/{title}", DeleteBook).Methods("DELETE")
http.ListenAndServe(":8080", r)
}
func CreateBook(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
w.WriteHeader(http.StatusOK)
fmt.Fprintf(w, "CreateBook: %v\n", vars["title"])
}
func ReadBook(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
w.WriteHeader(http.StatusOK)
fmt.Fprintf(w, "ReadBook: %v\n", vars["title"])
}
func UpdateBook(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
w.WriteHeader(http.StatusOK)
fmt.Fprintf(w, "UpdateBook: %v\n", vars["title"])
}
func DeleteBook(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
w.WriteHeader(http.StatusOK)
fmt.Fprintf(w, "DeleteBook: %v\n", vars["title"])
}
2. Request Forwarding
Suppose we start two servers, where server1 listens to port 8081 and server2 listens to port 8080.
server1:
func main() {
http.HandleFunc("/", func (w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Welcome to my website!")
})
http.ListenAndServe(":8081", nil)
}
server2:
func main() {
r := mux.NewRouter()
r.HandleFunc("/books/{title}", BookHandler).Host("localhost:8081")
http.ListenAndServe(":8080", r)
}
Since the request is forwarded in server2, /books/{title}
the request will be forwarded to server1, so the access http://localhost:8081/books/红楼梦
is valid.
3. Separately process https and http requests
Functions can be used Schemes
to distinguish whether the request is https or http and then handed over to different handlers for processing.
func main() {
r := mux.NewRouter()
r.HandleFunc("/secure", SecureHandler).Schemes("https")
r.HandleFunc("/insecure", InsecureHandler).Schemes("http")
http.ListenAndServe(":8080", r)
}
4. Sub-routing forwarding
Match the request according to a specific prefix, and forward the request as a sub-router. As follows, when the request is http://localhost:8080/books/
, call the AllBooks function. When the request is http://localhost:8080/books/红楼梦
, call the GetBook function.
func main() {
r := mux.NewRouter()
bookrouter := r.PathPrefix("/books").Subrouter()
bookrouter.HandleFunc("/", AllBooks)
bookrouter.HandleFunc("/{title}", GetBook)
http.ListenAndServe(":8080", r)
}