go web

前言

参考链接
这个教程是原生的库net/http来进行web服务端开发的 教程中使用了html/template来加载HTML模板 模板的语法也跟Python的jinja2的数据绑定很类似 但是我们清楚这种前后端不分离的方式其实不再合适未来的趋势


视图函数

go原生的net/http比较有意思 它的视图函数没有返回值也是可以的 它的http.HandleFunc这个装饰器可以默认返回空 不会报错 相反Python的一些框架就不行

一般视图函数格式 http.ResponseWriter用来写入返回给客户端的头部信息或者[]byte类型数据 *http.Request注意是一个指针类型 其实这里我有点不是很明白 怎么request是按照指针传递 response是按照值传递?

我自己觉得应该是在go语言中 response是从开发人员自己生命定义的handle视图函数开始就被一层一层的wrapper包装 所以response是不断被层层包裹被修改的 在每一层wrapper中response都不一样 所以按值传递就可以 但是requestsh1i是在各层wrapper或者redirect过程中都需要保持不变的 因为request是的参数被修改的话会影响http response这样没有太大意义 所以request最好使用指针传递 原来的request该怎样就怎样

stackoverflow的上关于这个问题的解释是

  • http.request是一个很大的结构 值拷贝的话花销非常大
  • http.request是含有一些状态state的 如果被拷贝的话具有一定的迷惑性
1
2
3
4
5
func handler(w http.ResponseWriter, r *http.Request)  {
p := r.URL.Path
fmt.Println("path", p)
w.Write([]byte("lalallallala"))
}

注册视图函数

1
http.HandleFunc("/", handler)

运行web后端app

1
http.ListenAndServe(":8080", nil)

上面是不会打印输出任何内容的 所以一般下面这样运行

1
log.Fatal(http.ListenAndServe(":8080", nil))

一般ip地址是可以被忽略的 默认是本机的IP地址

一般来说我们希望运行多个实例 然后在nginx上可以设置负载均衡 但是刚刚说上面那个监听运行语句是阻塞的 所以go语言这种天生支持多线程的的语言的优势就派上用场了

可以使用goroutine多开线程运行多个web app

1
2
3
4
5
for i := 0; i < 4; i++ {
go func() {
log.Fatal(http.ListenAndServe(":808" + string(i), nil))
}()
}

html模板加载和渲染就不记录了 就是使用原生的html/template这个库 语法非常类似Python的jinja2 感觉这部分在日益前后端分离的今天有点不合时宜了 所以只是看了看 没有多加记录