Go Web开发入坑指南

https://juejin.im/post/5c98a46fe51d4572d07e2b66

在Go语言中开发Web应用,真的是一件非常简单的事情,因为Go语言标准库中就有非常成熟且简单的Web开发包:net/http

net/http封装了开发Web应用所需要的大部分功能,因此,在Go语言中使用net/http开发Web应用程序时,我们甚至都不用像其他语言(比如PHP)一样需要自己再搭一个Apache或nginx等Web服务器,而是只需要简单几行代码就可以搭建一个Web服务应用。

Web基础

当然,虽然使用Go的net/http包可以简单开发Web应用,但我们在开发中仍然需要牢固地掌握开发Web程序所需要的基础知识,而Web开发中最基础和最核心的知识就是:HTTP协议

http协议是Web服务器与客户端(最常见就是浏览器)之间通讯的语言与规范,浏览器向Web发起请求到Web服务器响应并结束连接,整个过程如下图所示:






图片摘自《HTTP权威指南》

请求与响应

一个完整http事务,由一个客户端的请求和Web服务器响应构成,客户端发起的请求,包括三个部分:请求行请求头请求体,而Web服务器的响应同样包含三部分:响应行响应头响应体,如下图所示:。






图片摘自《HTTP权威指南》

http协议的相关知识远不只这些,我们有空再谈谈。

Go创建Web服务器的几种方式

http.HandleFunc函数

使用HandleFunc函数是http封装好的一个函数,可以直接使用,第一个参数是web请求路径,第二个参数是的func(writer http.ResponseWriter, request *http.Request)函数。

再使用http.ListenAndServe(":8080",nil)语句,监听8080端口,运行程序后。

使用http://localhost:8080,便会输出`一起学习Go Web编程吧`。

其中http.ResponseWriter代表对客户端的响应体,而http.Request代表客户端发送服务器的请求数据。

  1. func hello(writer http.ResponseWriter, request *http.Request) {
  2. writer.Write([]byte("一起学习Go Web编程吧"));
  3. }
  4. func main(){
  5. http.HandleFunc("/hello",hello)
  6. log.Fatal(http.ListenAndServe(":8080",nil))
  7. }

http.Handle函数

HandleFunc一样,Handle也是http封装好的函数,第一个参数跟HandleFunc一样,而第二个参数则是必须是实现了http.Handler接口的类型,http.Handler在http包的定义如下:

  1. type Handler interface {
  2. ServeHTTP(ResponseWriter, *Request)
  3. }

下面我们定义一个Controller结构体,在该结构定义ServeHTTP方法,因此Controller结构也实现http.Handler接口,而通过http.HandlerFunc也能将hello方法转成一个实现http.HandlerFunchttp.HandlerFunc也实现http.Handlerhttp.HandlerFunc在http包的定义如下:

  1. type HandlerFunc func(ResponseWriter, *Request)
  2. // ServeHTTP calls f(w, r).
  3. func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
  4. f(w, r)
  5. }

其实,在上面的例子中,我们将hello传给http.HandleFunc函数时,HandleFunc函数也是使用http.HandlerFunc将hello转换成http.HandlerFunc的。

下面有关http.Handle的示例:

  1. type Controller struct {}
  2. func (c Controller)ServeHTTP(writer http.ResponseWriter, request *http.Request){
  3. writer.Write([]byte("hello,1"));
  4. }
  5. func hello(writer http.ResponseWriter, request *http.Request) {
  6. writer.Write([]byte("hello,2"));
  7. }
  8. func main(){
  9. http.Handle("/hello1",&Controller{})
  10. http.Handle("/hello2",http.HandlerFunc(hello))
  11. log.Fatal(http.ListenAndServe(":8080",nil))
  12. }

运行程序后,在浏览器输入下面的地址:

http://localhost:8080/hell1, 输出:hello,1

http://localhost:8080/hell2, 输出:hello,2

http.ServeMux

无论是使用http.Handle还是http.HandleFunc函数,其实底层代码都是使用http.DefaultServeMuxDefaultServeMux的定义如下代码所示:

  1. var DefaultServeMux = &defaultServeMux
  2. var defaultServeMux ServeMux
  1. type Controller struct {}
  2. func (c Controller)ServeHTTP(writer http.ResponseWriter, request *http.Request){
  3. writer.Write([]byte("hello,1"));
  4. }
  5. func hello(writer http.ResponseWriter, request *http.Request) {
  6. writer.Write([]byte("hello,2"));
  7. }
  8. func main(){
  9. mux := &http.ServeMux{}
  10. mux.HandleFunc("/hello1",hello)
  11. mux.Handle("/hello2",http.HandlerFunc(hello))
  12. mux.Handle("/hello3",&Controller{})
  13. log.Fatal(http.ListenAndServe(":8080",mux))
  14. }

运行程序后,在浏览器输入下面的地址:

http://localhost:8080/hell1, 输出:hello,1

http://localhost:8080/hell2, 输出:hello,1

http://localhost:8080/hell3, 输出:hello,2

http.Server

http.Server是http包中对web更加底层的支持,我们前面使用的方法,都是对http.Server的封装而已,如果直接使用http.Server,则可以自定义更多的参数,如果连接超时等参数,因此我们下面直接使用http.Server开发Web服务。

  1. func main() {
  2. myHandler := &http.ServeMux{}
  3. myHandler.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
  4. w.Write([]byte("hello"))
  5. })
  6. s := &http.Server{
  7. Addr: ":8080",
  8. Handler: myHandler,
  9. ReadTimeout: 10 * time.Second,
  10. WriteTimeout: 10 * time.Second,
  11. MaxHeaderBytes: 1 << 20,
  12. }
  13. log.Fatal(s.ListenAndServe())
  14. }

运行程序后,在浏览器输入下面的地址:

http://localhost:8080/hello, 输出:hello

总结

通过上面的例子,可以看出Go Web开发可很简单,但是实际中,一个真正Web应用所要做的事,远不只这么简单,对于Go Web开发,还是有很多东西要学的。

ft_authoradmin  ft_create_time2019-08-03 17:13
 ft_update_time2019-08-03 17:13