前言
我一直这么认为:不会一门语言不能说自己是搞IT的,不会数据结构不能说自己是搞开发的。
用了15天时间复习了一遍go语言,自我感觉小有成就。在学数据结构和web之间纠结。最终决定先web后数据结构。
go语言的原生net/http就已经足够优秀了,go也有几个出名的框架。我选择从gin框架入门web。框架是一个已经搭建起来的舞台,可以在这个舞台上进行自己的表演,虽有局限,但总是便捷。
学习资料参考:https://www.liwenzhou.com/posts/Go/Gin_framework/
原生net/http学习参考:链接:https://pan.baidu.com/s/16y_Gne7DiWq4yCwVhqKOdw 提取码:olzo
计划一个星期入门gin 一个星期拿出项目。
web开发的本质
最最最重要的一张图 一个请求对应一个响应
牢记以下三点:
请求:客户端发起请求(HTTP协议)
处理:服务器处理请求
响应:服务器将处理结果发送给客户端’
用户访问网站的基本流程:https://blog.csdn.net/zisefeizhu/article/details/81031862
开始
新建项目:
用net/http库写个简单的web
net/http库:https://www.liwenzhou.com/posts/Go/go_http/
//main.go
package main
import (
"fmt"
"io/ioutil"
"net/http"
)
func sayHello(w http.ResponseWriter, r *http.Request) {
//file, err := os.Open("./hello.txt")
//if err != nil {
// fmt.Println("Open file err = ", err)
//}
//defer file.Close()
//const (
// defaultBufSize = 4096
//)
//reader := bufio.NewReader(file)
//for {
// str ,err := reader.ReadString('
')
// if err == io.EOF {
// break
// }
// _, _ = fmt.Fprintln(w,string(str) )
//}
b, _ := ioutil.ReadFile("./hello.txt") //内容不是特别多
_, _ = fmt.Fprintln(w,string(b) )
}
func main() {
http.HandleFunc("/hello",sayHello)
err := http.ListenAndServe(":8080",nil)
if err != nil {
fmt.Printf("http serve failed, err:%v
", err)
return
}
}
//hello.txt
<h1 style='color:red'>Hello zisefeizhu</h1>
<h2 style='color:yellow'> How are you ,jingxing</h2>
<h3 style='color:green'>Hello yike</h3>
<img id='i1' src='http://pic.baike.soso.com/ugc/baikepic2/7300/cov-20181211225313-1925802771_jpg_570_711_43751.jpg/300'>
<button id='b1'>点我</button>
<script>
document.getElementById('b1').onclick=function(){
document.getElementById('i1').src='http://pic.baike.soso.com/ugc/baikepic2/14050/20170916105801-135337938_jpg_374_479_21448.jpg/0'
}
</script>
E:gostudentgin>go run main.go
浏览器访问:
点击点我
完成最最简单的web
我们关注的不是hello.txt里面的内容,这是前端的问题。函数调用才是关注的点。
gin安装及简单使用
gin 中文文档:https://gin-gonic.com/zh-cn/docs/
下载并安装Gin
E:gostudentgin>go get -u github.com/gin-gonic/gin
示例
import "github.com/gin-gonic/gin"
func sauHello(c *gin.Context) {
c.JSON(200,gin.H{ //// c.JSON:返回JSON格式的数据
"message": "Hello zisefeizhu",
})
}
func main() {
//创建一个默认的路由引擎
r := gin.Default()
// GET:请求方式;/hello:请求的路径
// 当客户端以GET方法请求/hello路径时,会执行后面的sayHello函数
r.GET("/hello", sauHello)
//启动HTTP服务,默认在0.0.0.0:8080启动服务
r.Run()
//r.Run(":9090") //改端口
}
E:gostudentgin>go run main.go //显示defug
[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- using env: export GIN_MODE=release
- using code: gin.SetMode(gin.ReleaseMode)
[GIN-debug] GET /hello --> main.sauHello (3 handlers)
[GIN-debug] Environment variable PORT is undefined. Using port :8080 by default
[GIN-debug] Listening and serving HTTP on :8080
浏览器
将上面的代码保存并编译执行,然后使用浏览器打开127.0.0.1:8080/hello就能看到一串JSON字符串。
RESTFUL API
REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移”或“表现层状态转化”。
简单来说,REST的含义就是客户端与Web服务器之间进行交互的时候,使用HTTP协议中的4个请求方法代表不同的动作。
- GET用来获取资源
- POST用来新建资源
- PUT用来更新资源
- DELETE用来删除资源
只要API程序遵循了REST风格,那就可以称其为RESTful API。目前在前后端分离的架构中,前后端基本都是通过RESTful API来进行交互。
举例:现在要编写一个管理书籍的系统,我们可以查询对一本书进行查询、创建、更新和删除等操作,我们在编写程序的时候就要设计客户端浏览器与我们Web服务端交互的方式和路径。
请求方法 | URL | 含义 |
---|---|---|
GET | /book | 查询书籍信息 |
POST | /book | 创建书籍记录 |
PUT | /book | 更新书籍信息 |
DELETE | /book | 删除书籍信息 |
Gin框架支持RESTful API的开发。
简单入门
import "github.com/gin-gonic/gin"
func main() {
//创建一个默认的路由引擎
r := gin.Default()
// r.XXX:请求方式;/book:请求的路径
// 当客户端以XXX方法请求/book路径时,会执行后面的匿名函数
r.GET("/book", func(c *gin.Context) {
c.JSON(200,gin.H{
"message" : "GET",
})
})
r.POST("/book", func(c *gin.Context) {
c.JSON(200,gin.H{
"message":"POST",
})
})
r.PUT("/book", func(c *gin.Context) {
c.JSON(200,gin.H{
"message":"PUT",
})
})
r.DELETE("/book", func(c *gin.Context) {
c.JSON(200,gin.H{
"message":"DELETE",
})
})
//r.Run("9090")
r.Run(":9090")
}
开发RESTful API的时候我们通常使用Postman来作为客户端的测试工具。
import (
"github.com/gin-gonic/gin"
"net/http"
)
func main() {
r := gin.Default()
r.GET("/ping", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "pong",
})
})
r.Run(":9090")
}
匹配所有请求方法
func main() {
r := gin.Default()
r.Any("/ping", func(c *gin.Context) { //Any方法
c.JSON(http.StatusOK, gin.H{
"message": "pong",
})
})
r.Run(":9090")
}