前言
我一直這么認為:不會一門語言不能說自己是搞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('\n')
// 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\n", 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:\gostudent\gin>go run main.go
瀏覽器訪問:
點擊點我
完成最最簡單的web
我們關注的不是hello.txt里面的內容,這是前端的問題。函數調用才是關注的點。
gin安裝及簡單使用
gin 中文文檔:https://gin-gonic.com/zh-cn/docs/
下載並安裝Gin
E:\gostudent\gin>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:\gostudent\gin>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")
}