มิดเดิลแวร์ - ขั้นสูง
ตัวอย่างต่อไปนี้จะแสดงวิธีการสร้าง มิดเดิลแวร์ขั้นสูง ในภาษา Go
ตัวมิดเดิลแวร์จะทำการรับ http.HandlerFunc
ในรูปแบบของตัวแปร และทำการครอบมันไว้แล้วจึงส่งค่ากลับไปเป็น http.HandlerFunc
ตัวใหม่ให้กับเซิร์ฟเวอร์เพื่อรอการเรียกใช้งาน
นี่คือคำจัดกัดความใหม่ของ Middleware
ซึ่งจะทำให้ง่ายต่อการผูก (chain) มิดเดอแวร์หลายๆ ตัวเข้าไว้ด้วยกัน ความคิดนี้ได้รับแรงบันดาลใจมาจาก Mat Ryers ซึ่งได้เคยพูดไว้ในเรื่องเกี่ยวกับการสร้าง APIs ถ้าหากต้องการรู้รายละเอียดเพ่ิมเติม สามารถเข้าไปดูได้ที่ here.
ตัวอย่างโค้ต่อไปนี่ใช้เพื่อสร้าง มิดเดิลเวร์ตัวใหม่ และในตัวอย่างตัวเต็มเราได้ใช้ตัวอย่างโค้ดสำเร็จรูปในการสร้างเพื่อความรวดเร็ว
func createNewMiddleware() Middleware {
// Create a new Middleware
middleware := func(next http.HandlerFunc) http.HandlerFunc {
// Define the http.HandlerFunc which is called by the server eventually
handler := func(w http.ResponseWriter, r *http.Request) {
// ... do middleware things
// Call the next middleware/handler in chain
next(w, r)
}
// Return newly created handler
return handler
}
// Return newly created middleware
return middleware
}
นี่คือตัวอย่างตัวเต็ม:
// advanced-middleware.go
package main
import (
"fmt"
"log"
"net/http"
"time"
)
type Middleware func(http.HandlerFunc) http.HandlerFunc
// Logging logs all requests with its path and the time it took to process
func Logging() Middleware {
// Create a new Middleware
return func(f http.HandlerFunc) http.HandlerFunc {
// Define the http.HandlerFunc
return func(w http.ResponseWriter, r *http.Request) {
// Do middleware things
start := time.Now()
defer func() { log.Println(r.URL.Path, time.Since(start)) }()
// Call the next middleware/handler in chain
f(w, r)
}
}
}
// Method ensures that url can only be requested with a specific method, else returns a 400 Bad Request
func Method(m string) Middleware {
// Create a new Middleware
return func(f http.HandlerFunc) http.HandlerFunc {
// Define the http.HandlerFunc
return func(w http.ResponseWriter, r *http.Request) {
// Do middleware things
if r.Method != m {
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
return
}
// Call the next middleware/handler in chain
f(w, r)
}
}
}
// Chain applies middlewares to a http.HandlerFunc
func Chain(f http.HandlerFunc, middlewares ...Middleware) http.HandlerFunc {
for _, m := range middlewares {
f = m(f)
}
return f
}
func Hello(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "hello world")
}
func main() {
http.HandleFunc("/", Chain(Hello, Method("GET"), Logging()))
http.ListenAndServe(":8080", nil)
}
$ go run advanced-middleware.go
2017/02/11 00:34:53 / 0s
$ curl -s http://localhost:8080/
hello world
$ curl -s -XPOST http://localhost:8080/
Bad Request