我该如何对的起这句话呢?
熟练使用 Golang 进行 HTTP 服务开发,具备基础接口设计与健康检查实现经验
什么是HTTP?
这个我们都不陌生。TCP/UDP也知道吧。但是它们是如何实现的呢?
Gin用的太久了,很多底层的东西,我几乎不知道。
http服务,监听,处理。 监听路径,处理。
一个URL对应一个请求的处理器,构成了http请求的核心。
这就是http.Handle()的两个参数。
go
func Handle(pattern string, handler Handler)
http.Handle是一切的起点。
pattern 是string,handler 的是Handler。
作为数据类型,string我们很好理解。但是Handler是什么呢?
我们来查看源码
go
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
显然,Handler 是一个接口。任何一个实现了ServeHTTP(ResponseWriter, *Request)方法且无返回值的数据type,都可以作为Handler 来使用。
这就是第一种做法。
go
package main
import (
"net/http"
)
type my_handler struct{}
func (f my_handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello World"))
}
func main() {
http.Handle("/", my_handler{})
http.ListenAndServe("0.0.0.0:8080", nil)
}
同时,如果我们只需要写对应的处理逻辑,而不需要一个具体的结构体,再实现ServeHTTP呢?
这就出来了第2种方法:
go
// The HandlerFunc type is an adapter to allow the use of
// ordinary functions as HTTP handlers. If f is a function
// with the appropriate signature, HandlerFunc(f) is a
// [Handler] that calls f.
type HandlerFunc func(ResponseWriter, *Request)
// ServeHTTP calls f(w, r).
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
f(w, r)
}
由于HandlerFunc 的特殊设计,导致我们可以将我们的具体的代码逻辑写成一个普通的函数,当然这个普通函数的函数签名和返回值与ServeHTTP一样。然后这个函数就可以作为HandlerFunc 的参数构建一个实例,这个实例就可以作为Handler 来使用。
go
package main
import (
"net/http"
)
func rootHandler(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello World"))
}
func main() {
http.Handle("/", http.HandlerFunc(rootHandler))
http.ListenAndServe("0.0.0.0:8080", nil)
}
当然也可以直接写匿名函数:
go
package main
import (
"net/http"
)
func main() {
http.Handle("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello World"))
}))
http.ListenAndServe("0.0.0.0:8080", nil)
}
难道我们不能直接将普通函数作为参数传入吗?能不能再多封装一点方便我们做开发?
那就是第3种方法:
go
package main
import (
"net/http"
)
func rootHandler(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello World"))
}
func main() {
http.HandleFunc("/", rootHandler)
http.ListenAndServe("0.0.0.0:8080", nil)
}
当然,我们也可以写匿名函数:
go
package main
import (
"net/http"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello World"))
})
http.ListenAndServe("0.0.0.0:8080", nil)
}