go從0到1項目實戰體系二十二:gin構建一個http server

1. 構建一個http server:

// api.test.com/topic/main.go:
type Topic struct {Id int           // 如果寫成小寫的,不能訪問,因為是私有的.Title string
}
func main() {data := make(map[string]interface{})data["name"] = "david"data["age"] = 12// 默認路由router := gin.Default()router.GET("/", func(context *gin.Context) {context.Writer.Write([]byte("hello"))                                 // (1)// context.JSON(http.StatusOK, data)                                  // (2)// context.JSON(http.StatusOK, gin.H{"name": "daivd", "age": 12})     // (3)// context.JSON(http.StatusOK, Topic{100, "話題標題"})                 // (4)})router.Run()
}

(1). 返回text/plain格式的結果:hello

HTTP/1.1 200 OK
Date: Fri, 01 Nov 2019 04:09:18 GMT
Content-Length: 5
Content-Type: text/plain; charset=utf-8

(2). 返回json的格式:{“age”:12, “name”:“david”}

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Date: Mon, 04 Nov 2019 11:00:06 GMT
Content-Length: 25

(3). 返回如上json的格式:{“age”:12, “name”:“david”}

# 1. gin.H{}底層實現方案:
// H is a shortcut for map[string]interface{}
type H map[string]interface{}# 2. 模擬實現:
type M map[string]interface{}. make的形式:m := make(M)m["name"] = "david"# 在使用map,需要先make,make的作用就是給map分配數據空間②. 直接賦值:map[string]interface{}{"name": "daivd"}. M就相當于map[string]interface{}的簡寫:M{"name": "daivd"}

(4). 對象返回如上json的格式:{“Id”:100, “Title”:“話題標題”}


2. API的URL規則設計:

2.1 httprouter庫:

①. gin的路由使用的是httprouter庫.
②. 不支持正則、不支持固定路徑和參數路徑.
③. 保證了性能,但功能不強大.

2.2 API設計建議:

(1). 常規上的路由:

GET /topic/{topic_id}:獲取帖子明細
GET /topic/{user_name}:獲取用戶發布的帖子列表
GET /topic/top:獲取最熱帖子列表

(2). 建議改進路由規則:

①. 最好API前面加上版本:GET /v1/topic/:id②. 盡可能使用復數的語義化名詞:GET /v1/topics③. 使用GET參數規劃數據展現規則:GET /v1/users                  // 顯示全部用戶GET /v1/users?limit=10         // 顯示10條用戶GET /v1/topics?username=xx     // 顯示xx的帖子

3.3 增加其它路由:

api.test.com/topic/main.go:

router := gin.Default()
router.GET("/v1/topics/:topic_id", func(context *gin.Context) {context.String(http.StatusOK, "獲取%s的帖子", context.Param("topic_id"))
})
router.GET("/v1/topics", func(context *gin.Context) {if context.Query("username") == "" {context.String(http.StatusOK, "獲取所有帖子")} else {context.String(http.StatusOK, "獲取%s所有帖子", context.Query("username"))}
})
router.Run()

注:

①. 以下幾條路由不允許:router.GET("/topic/:id")router.GET("/topic/topic")router.GET("/topic/topic/:username")②. 報錯:panic: 'topic' in new path '/topic/topic' conflicts with existing wildcard ':topic_id' in existing prefix '/:topic_id'③. context.Param可以獲取"/v1/topics/:topic_id"中以冒號的形式設置url參數topic_id.④. context.Query可以當get傳參的時候,url上顯示的參數.

3.4 路由分組:

(1). api.test.com/topic/main.go:

import "topic.test.com/src"  // moduel/文件名
func main() {router := gin.Default()// 定義一個路由分組v1 := router.Group("/v1/topics")// {}不是強關聯,只是為了美觀,做代碼切割,不寫也可以,有作用域的區別{// 什么都不寫,表示與組的路由是一致的(GET /v1/topics)v1.GET("", src.GetList)  // 將業務代碼分離出去v1.GET("/:topic_id", func(context *gin.Context) {context.String(http.StatusOK, "獲取%s的帖子", context.Param("topic_id"))})// 在這個下面所有定義的路由都需要鑒權v1.Use(src.MustLogin()){v1.POST("", src.AddTopic)}}router.Run()
}:. 如果src.GetList(),不想寫src的話.需要這樣引入  =>  . "topic.test.com/src". 不能寫src.GetList(),否則是表示執行函數得到的結果.. 如果想寫src.GetList(),則需要改造如下:func GetList2() gin.HandlerFunc {return func (c *gin.Context) {//}}. v1.Use的參數為HandlerFunc,所以是執行函數返回結果.. 為了美觀,可以在路由上加一個{}代碼塊(代碼塊有作用域),不是強關聯,只是為了美觀.

(2). api.test.com/topic/src/TopicDao.go:

src是所有業務代碼

func MustLogin() gin.HandlerFunc {return func (c *gin.Context) {if _, status := c.GetQuery("token");!status {c.String(http.StatusUnauthorized, "授權失敗")c.Abort()  // 沒有的話,會繼續往下執行} else {c.Next()}}
}
func GetList(c *gin.Context) {// if c.Query("username") == "" {//  	c.String(http.StatusOK, "獲取所有帖子")// } else {//  	c.String(http.StatusOK, "獲取%s所有帖子", c.Query("username"))// }// get參數校驗query := TopicQuery{}err := c.BindQuery(&query)  // 是BindQueryif err != nil {c.JSON(500, "參數錯誤")  // 自動報一個400 Bad Request的錯誤,寫成500也是400} else {c.JSON(http.StatusOK, query)}
}
func AddTopic(c *gin.Context) {// c.JSON(http.StatusOK, CreateTopic(1, "PHP"))// post參數校驗query := Topic{}err := c.BindJSON(&query)  // 是BindJSONif err != nil {c.JSON(500, "參數錯誤")} else {c.JSON(http.StatusOK, query)}
}:. Dao層操作數據庫實體、redis實體.. 路由測試:POST localhost:8080/v1/topics  => 結果是:授權失敗POST localhost:8080/v1/topics?token=123  => 結果是:{ "id": 1, "title": "PHP" }如果沒有json映射字段則返回:{ "TopicId": 1, "TopicTitle": "PHP" }. 參數綁定Model:a. GetList中,如果參數有username、page、pagesize等,if來判斷的話,非常繁瑣.b. 可以將get參數綁定(get參數映射為一個模型).c. 很多流行框架支持參數綁定Model(傳過來的參數與model進行綁定).. GET localhost:8080/v1/topics?username=david&page=1&pagesize=10=> 如果TopicQuery struct中沒有form字段會是{ "username": "", "page": 0, "pagesize": 0 }localhost:8080/v1/topics?username=david&page=1=> { "username": "david", "page": 1, "pagesize": 0 }localhost:8080/v1/topics?username=david&page=1&pagesize=10=> { "username": "david", "page": 1, "pagesize": 10 }localhost:8080/v1/topics?username=david&pagesize=10=> 參數錯誤localhost:8080/v1/topics?username=david&page=0=> 參數錯誤,page為0localhost:8080/v1/topics?username=david&page=""=> 參數錯誤,page為""

(3). api.test.com/topic/src/TopicModel.go:

package src
type Topic struct {TopicId int `json:"id"`  // json反射的映射字段TopicTitle string `json:"title" binding:"min=4,max=20"`  // 在4和20字之間,中英文都是一樣TopicShortTitle string `json:"stitle" binding:"requried,nefield=TopicTitle"`  // 不能與TopicTitle一樣UserIP string `json:"ip" binding:"ipv4"`TopicScore int `json:"score" binding:"omitempty,gt=5"`  // 可以不填,填了就大于5TopicUrl string `json:"url" binding:"omitempty,topicurl"`
}
func CreateTopic (id int, title string) Topic {return Topic{id, title}
}
// query參數綁定
type TopicQuery struct {UserName string `json:"username" form:"username"`Page int `json:"page" form:"page" binding:"required"`PageSize int `json:"pagesize" form:"pagesize"`
}:. form決定了綁定query參數的key到底是什么.沒寫form,則不會綁定.. 內置驗證器是第三方庫github.com/go-playground/validator

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/536734.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/536734.shtml
英文地址,請注明出處:http://en.pswp.cn/news/536734.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

TwIST算法MALTLAB主程序詳解

TwIST算法MALTLAB主程序詳解 關于TwIST算法的具體原理可以參考: 鏈接: https://ieeexplore.ieee.org/abstract/document/4358846 鏈接: https://blog.csdn.net/jbb0523/article/details/52193209 該算法的MATLAB源代碼: 鏈接: http://www.lx.it.pt/~bi…

tcp和udp協議分別是什么意思有什么區別?

TCP(傳輸控制協議)和UDP(用戶數據報協議)是兩種網絡傳輸協議,它們在網絡通信中有一些關鍵的區別。 連接性: TCP: 提供面向連接的服務。在通信之前,需要建立連接,數據傳輸…

Node.js(二)-模塊化

1. 模塊化的基本概念 1.1 什么是模塊化 模塊化是指解決一個復雜問題時,自頂向下逐層將系統拆分成若干模塊的過程。對于整個系統來說,模塊是可組合、分解和更換的單元。 1.2 編程領域中的模塊化 編程領域中的模塊化,就是遵守固定的規則&…

48V轉12V 300mA降壓芯片,60V耐壓、0.6A穩壓芯片帶ECO模式-AH590L

AH590L是一種48V轉12V 300mA降壓芯片,具有60V耐壓、0.6A穩壓電流的特點,并且還帶有ECO模式,是一種理想的開關電源解決方案。 AH590L是PWM模式 DC/DC降壓轉換器。TEL:l86*4884*3702*寬輸入電壓范圍4至60V適用于工業領域的廣泛應用…

有意思、好用的免費API分享

Facebook Games Services - Facebook Games Services 為游戲開發者提供了各種服務, 包括(但不限于) 成就 API, 分數 API, 應用通知, 請求, 游戲養成和 Facebook SDK for Unity.Google Play Games Services - Google Developers Games 網站提供了各種 API, SDK 和服務, 包括(但不…

AI安全綜述

1、引言 AI安全這個話題,通常會引伸出來圖像識別領域的對抗樣本攻擊。下面這張把“熊貓”變“猴子”的攻擊樣例應該都不陌生,包括很多照片/視頻過人臉的演示也很多。 對抗樣本的研究領域已經具備了一定的成熟性,有一系列的理論來論述對抗樣本…

解決jquery-1.11.0.js安全漏洞

摘要:這個文件被掃出安全漏洞有XSS攻擊等 ,其中一個比較著名的漏洞是在JQuery 1.6.2版本中發現的。該漏洞被稱為”attrFn"漏洞,它允許攻擊者通過特殊構造的代碼執行任意的JavaScript代碼。 一、統一解決方式: jQuery官網 官…

javafx實現復雜統計圖繪畫

JavaFX 是一個用于創建富互聯網應用程序 (Rich Internet Applications) 的軟件平臺,可以用于創建各種圖形和圖表。下面是一個示例代碼,演示如何使用 JavaFX 繪制復雜的統計圖。 import javafx.application.Application; import javafx.collections.FXCollections; import ja…

one wire(單總線)FPGA代碼篇

一.引言 單總線(OneWire)是一種串行通信協議,它允許多個設備通過一個單一的數據線進行通信。這個協議通常用于低速、短距離的數字通信,特別適用于嵌入式系統和傳感器網絡。 二.one wire通信優點缺點 優點: 單一數據線…

Unity程序向Web服務器發送數據

Unity程序向Web服務器發送數據 一、介紹二、HTTP協議三、新建Unity工程,創建腳本1.新建Unity工程,創建腳本WebManager.cs,將其指定給場景中的任意游戲體。2.在WebManager.cs中添加一個m_info屬性和OnGUI函數顯示UI: 四、GET請求在…

npm使用詳解(好吧好吧是粗解)

目錄 npm是什么? npm有什么用? npm安裝 在 Windows 上 在 macOS 上 在 Linux 上(使用 apt 包管理器為例) 驗證 npm 安裝成功: npm使用 1. 初始化項目: 2. 安裝和管理依賴: 3. 查看和…

【DataV】DataV組件庫——更新數據視圖不更新

參考文章:dataV組件庫——改變數據視圖不主動刷新 問題: 拿到后端數值就直接賦值了,但是視圖(頁面)沒有更新。 解決: 官方文檔介紹dataV里面的組件props均未設置deep監聽,刷新props時&#xf…

一個利用摸魚時間背單詞的軟件

大家好,我是 Java陳序員。 最近進入了考試季,各種考試,英語四六級、考研、期末考等。不知道大家的英語四六級成績怎么樣呢? 記得大學時,英語四級都是靠高中學習積累的老本才勉強過關。 而六級則是考了多次&#xff…

20231224解決outcommit_id.xml1 parser error Document is empty的問題

20231224解決outcommit_id.xml1 parser error Document is empty的問題 2023/12/24 18:13 在開發RK3399的Android10的時候,出現:rootrootrootroot-X99-Turbo:~/3TB/Rockchip_Android10.0_SDK_Release$ make installclean PLATFORM_VERSION_CODENAMEREL…

靜態HTTP的常見問題和解決方法

大家好,歡迎來到今天的“靜態HTTP大講堂”!今天我們要聊聊靜態HTTP的常見問題和解決方法。別小看這些問題哦,它們就像是那些頑皮的小妖精,時不時地給你的網站搞點惡作劇。不過別擔心,有我在,這些小妖精都得…

推薦一款好用的免費圖片轉換工具bmp轉png工具bmp2png

推薦一款好用的免費圖片轉換工具bmp轉png工具bmp2png 寫這個工具是因為要使用傳奇的部分素材在COCOS2DX使用,但是COCOS2DX不支持BMP如果直接將BMP轉換到PNG的話,網上找到的工具都不支持透明色轉換。難道要用PS一個一個摳圖嗎?要累死所以寫了…

HBase 超大表遷移、備份、還原、同步演練手冊:全量快照 + 實時同步(Snapshot + Replication)不停機遷移方案

博主歷時三年精心創作的《大數據平臺架構與原型實現:數據中臺建設實戰》一書現已由知名IT圖書品牌電子工業出版社博文視點出版發行,點擊《重磅推薦:建大數據平臺太難了!給我發個工程原型吧!》了解圖書詳情,京東購書鏈接:https://item.jd.com/12677623.html,掃描左側二維…

如何選擇適合業務的負載均衡策略?

在分布式系統的高可用設計中,負載均衡非常關鍵,我們知道,分布式系統的特性之一就是支持快速擴展,那么集群擴展之后,服務請求如何從服務器列表中選擇合適的一臺呢?這就需要依賴負載均衡策略。 負載均衡在處…

免 費 搭 建 小程序商城,打造多商家入駐的b2b2c、o2o、直播帶貨商城

在數字化時代,電商行業正經歷著前所未有的變革。鴻鵠云商的saas云平臺以其獨特的架構和先進的理念,為電商行業帶來了全新的商業模式和營銷策略。該平臺涉及多個平臺端,包括平臺管理、商家端、買家平臺、微服務平臺等,涵蓋了pc端、…

項目執行常用的ChatGPT通用提示詞模板

項目啟動與準備:如何確保項目按計劃啟動,并為項目執行做好充分準備? 任務分配與執行:如何合理分配任務,確保項目團隊成員明確各自的責任和目標? 進度監控與調整:如何實時監控項目進度&#xf…