Gin 路由注冊與請求參數(shù)獲取

Gin 路由注冊與請求參數(shù)獲取

一、Web應(yīng)用開發(fā)的兩種模式

1.前后端不分離模式

  • 也叫前后端混合開發(fā)模式, 需要后端寫模板語言(dtl), 返回的是HTML頁面
  • 瀏覽器 : 請求動態(tài)頁面
  • 后端 : 返回HTML

img

  • 優(yōu)點:可以直接渲染頁面, 方便處理請求數(shù)據(jù)

  • 缺點:耦合度非常高, 不方便擴展

2.前后端分離模式

  • 前端 : 只寫前端
  • 后端 : 只專注于寫后端接口, 返回 json, xml格式數(shù)據(jù)
  • 流程 :

瀏覽器到靜態(tài)文件服務(wù)器請求靜態(tài)頁面, 靜態(tài)服務(wù)器返回靜態(tài)頁面

JS 請求達(dá)到后端, 后端再返回 JSON 或 XML格式的數(shù)據(jù)

img

  • 優(yōu)點
  • 不需要管前端怎么實現(xiàn), 后端開發(fā)者需要做的就是寫接口
  • 只需要知道, 你前端傳過來什么, 然后需要后端這邊傳回去什么就行了
  • 主要的就是操作邏輯, 解耦合性高
  • 缺點
  • 程序員不知道前端的具體流程, 然后對表的設(shè)計, 對業(yè)務(wù)或許就理解的沒有那么透徹
  • 還存在前后端聯(lián)調(diào)各種問題, 前端和后端的溝通等

二、RESTful介紹

RESTful(Representational State Transfer)代表的是一種基于HTTP協(xié)議設(shè)計的軟件架構(gòu)風(fēng)格,它通常用于構(gòu)建Web服務(wù),是Representational State Transfer的簡稱,中文翻譯為“表征狀態(tài)轉(zhuǎn)移”或“表現(xiàn)層狀態(tài)轉(zhuǎn)化”。RESTful架構(gòu)的設(shè)計理念是將資源表示為URI(統(tǒng)一資源標(biāo)識符),通過HTTP協(xié)議的GET、POST、PUT、DELETE等方法對資源進(jìn)行操作。以下是RESTful架構(gòu)的一些關(guān)鍵特點:

  1. 資源(Resource):在RESTful架構(gòu)中,所有的數(shù)據(jù)或服務(wù)都被抽象為資源,每個資源都有一個唯一的標(biāo)識符(URI)。
  2. 表現(xiàn)層(Representation):資源的表現(xiàn)層是指資源在不同的表示形式之間進(jìn)行切換,通常使用JSON或XML格式。客戶端和服務(wù)器之間通過資源的表現(xiàn)層進(jìn)行通信。
  3. 狀態(tài)轉(zhuǎn)移(State Transfer):RESTful架構(gòu)通過HTTP方法(GET、POST、PUT、DELETE等)實現(xiàn)狀態(tài)的轉(zhuǎn)移,對資源進(jìn)行增刪改查的操作。
  4. 無狀態(tài)(Stateless):RESTful服務(wù)是無狀態(tài)的,每個請求都包含足夠的信息,使服務(wù)器能夠理解和處理請求,而無需依賴之前的請求。

三、API接口

3.1 RESTful API設(shè)計指南

參考資料 阮一峰 理解RESTful架構(gòu)

3.2 API與用戶的通信協(xié)議

總是使用HTTPs協(xié)議

3.3 RestFul API接口設(shè)計規(guī)范

3.3.1 api接口

  • 規(guī)定了前后臺信息交互規(guī)則的url鏈接,也就是前后臺信息交互的媒介

3.3.2 接口文檔:

  • 可以手動寫(公司有平臺,錄到平臺里)
  • 自動生成(coreapi,swagger)

3.4 restful規(guī)范(10條,規(guī)定了這么做,公司可以不采用)

  1. 數(shù)據(jù)的安全保障,通常使用https進(jìn)行傳輸

  2. 域名中會含有API標(biāo)識

    https://api.example.com 盡量將API部署在專用域名

    https://127.0.0.0:8080/api/ API很簡單

  3. 請求地址中帶版本信息,或者在請求頭中

    https://127.0.0.0:8080/api/v1/

  4. 任何東西都是資源,均使用名詞表示 (盡量不要用動詞)

    https://api.example.com/v1/books/

    https://api.example.com/v1/get_all_books(不符合規(guī)范)

  5. 請求方式區(qū)分不同操作

    • get獲?。簭姆?wù)器取出資源(一項或多項)

    • post新增數(shù)據(jù):在服務(wù)器新建一個資源

    • put/patch:patch是局部更新,put是全部(基本上更新都用put)

    • delete:從服務(wù)器中刪除

  6. 在請求路徑中帶過濾,通過在url上傳參的形式傳遞搜索條件

    https://api.example.com/v1/?name='金'&order=asc

    https://api.example.com/v1/name?sortby=name&order=asc

    https://api.example.com/v1/zoos?limit=10:指定返回記錄的數(shù)量

    https://api.example.com/v1/zoos?offset=10:指定返回記錄的開始位置

    https://api.example.com/v1/zoos?page=2&per_page=100:指定第幾頁,以及每頁的記錄數(shù)

    https://api.example.com/v1/zoos?sortby=name&order=asc:指定返回結(jié)果按照哪個屬性排序,以及排序順序

    https://api.example.com/v1/zoos?animal_type_id=1:指定篩選條件

  7. 返回數(shù)據(jù)中帶狀態(tài)碼

    • http請求的狀態(tài)碼

    • 返回的json格式中到狀態(tài)碼(標(biāo)志當(dāng)次請求成功或失敗)

      200 OK - [GET]:服務(wù)器成功返回用戶請求的數(shù)據(jù),該操作是冪等的(Idempotent)。
      201 CREATED - [POST/PUT/PATCH]:用戶新建或修改數(shù)據(jù)成功。
      202 Accepted - [*]:表示一個請求已經(jīng)進(jìn)入后臺排隊(異步任務(wù))
      204 NO CONTENT - [DELETE]:用戶刪除數(shù)據(jù)成功。
      400 INVALID REQUEST - [POST/PUT/PATCH]:用戶發(fā)出的請求有錯誤,服務(wù)器沒有進(jìn)行新建或修改數(shù)據(jù)的操作,該操作是冪等的。
      401 Unauthorized - [*]:表示用戶沒有權(quán)限(令牌、用戶名、密碼錯誤)。
      403 Forbidden - [*] 表示用戶得到授權(quán)(與401錯誤相對),但是訪問是被禁止的。
      404 NOT FOUND - [*]:用戶發(fā)出的請求針對的是不存在的記錄,服務(wù)器沒有進(jìn)行操作,該操作是冪等的。
      406 Not Acceptable - [GET]:用戶請求的格式不可得(比如用戶請求JSON格式,但是只有XML格式)。
      410 Gone -[GET]:用戶請求的資源被永久刪除,且不會再得到的。
      422 Unprocesable entity - [POST/PUT/PATCH] 當(dāng)創(chuàng)建一個對象時,發(fā)生一個驗證錯誤。
      500 INTERNAL SERVER ERROR - [*]:服務(wù)器發(fā)生錯誤,用戶將無法判斷發(fā)出的請求是否成功。
      

      更多狀態(tài)碼參考:http://tools.jb51.net/table/http_status_code

  8. 返回數(shù)據(jù)中帶錯誤信息

    • 錯誤處理,應(yīng)返回錯誤信息,error當(dāng)做key

      {
          error: "Invalid API key"
      }
      
  9. 對不同操作,返回數(shù)據(jù)符合如下規(guī)范(這只是規(guī)范)

    GET /books:返回資源對象的列表(數(shù)組)[{},{},{}]
    GET /books/1:返回單個資源對象    {}
    POST /books:返回新生成的資源對象  {新增的書}
    PUT /books/1:返回完整的資源對象   {返回修改后的}
    PATCH /books/1: 返回完整的資源對象  {返回修改后的}
    DELETE /books/1:  返回一個空文檔           
    
    {status:100,msg:查詢成功,data:null}
    
  10. 返回結(jié)果中帶連接

    RESTful API最好做到Hypermedia,即返回結(jié)果中提供鏈接,連向其他API方法,使得用戶不查文檔,也知道下一步應(yīng)該做什么。

    {"link": {
      "rel":   "collection https://www.example.com/zoos",
      "href":  "https://api.example.com/zoos",
      "title": "List of zoos",
      "type":  "application/vnd.yourformat+json"
    }}
    

四、圖書管理系統(tǒng)設(shè)計

例如,我們現(xiàn)在要編寫一個管理書籍的系統(tǒng),我們可以查詢對一本書進(jìn)行查詢、創(chuàng)建、更新和刪除等操作,我們在編寫程序的時候就要設(shè)計客戶端瀏覽器與我們Web服務(wù)端交互的方式和路徑。按照經(jīng)驗我們通常會設(shè)計成如下模式:

請求方法 URL 含義
GET /book 查詢書籍信息
POST /create_book 創(chuàng)建書籍記錄
POST /update_book 更新書籍信息
POST /delete_book 刪除書籍信息

同樣的需求我們按照RESTful API設(shè)計如下:

請求方法 URL 含義
GET /book 查詢書籍信息
POST /book 創(chuàng)建書籍記錄
PUT /book 更新書籍信息
DELETE /book 刪除書籍信息

新建一個book.go文件,鍵入如下代碼:

package main

import (
    "github.com/gin-gonic/gin"
    "net/http"
)

func main() {
    r := gin.Default()
    r.GET("/book", func(c *gin.Context) {
        c.String(http.StatusOK, "查詢書籍信息")
    })

    r.POST("/book", func(c *gin.Context) {
        c.String(http.StatusOK, "新增書籍信息")
    })

    r.PUT("/book", func(c *gin.Context) {
        c.String(http.StatusOK, "修改書籍信息")
    })

    r.DELETE("/book", func(c *gin.Context) {
        c.String(http.StatusOK, "刪除書籍信息")
    })
    r.Run(":8080")
}

接下來我們可以使用Postman來作為客戶端的來調(diào)用我們剛剛寫好的接口。

五、Gin 路由類型

Gin 支持很多類型的路由:

  • 靜態(tài)路由:完全匹配的路由,也就是前面 我們注冊的 hello 的路由。
  • 參數(shù)路由:在路徑中帶上了參數(shù)的路由。
  • 通配符路由:任意匹配的路由。

通配符路由

通配符路由究竟匹配上了什么,也是通過 Param 方法獲得的。

通配符路由不能注冊這種 /users/*,/users/*/a。也就是說,* 不能單獨出現(xiàn)。

六、路由參數(shù)

6.1 獲取URL后面的參數(shù)

  • URL參數(shù)可以通過DefaultQuery()Query()方法獲取
  • DefaultQuery()若參數(shù)不存在則返回默認(rèn)值,Query()若不存在,返回空串
  • 指的是URL中?后面攜帶的參數(shù),例如:/user/search?username=賈維斯&address=北京
func main() {
    //Default返回一個默認(rèn)的路由引擎
    r := gin.Default()
    r.GET("/user/search", func(c *gin.Context) {
        username := c.DefaultQuery("username", "賈維斯")
        //username := c.Query("username")
        address := c.Query("address")
        //輸出json結(jié)果給調(diào)用方
        c.JSON(http.StatusOK, gin.H{
            "message":  "ok",
            "username": username,
            "address":  address,
        })
    })
    r.Run()
}

6.2 獲取path參數(shù)

請求的參數(shù)通過URL路徑傳遞,例如:/user/search/賈維斯/北京。在Gin框架中,提供了c.Param方法可以獲取路徑中的參數(shù)。 獲取請求URL路徑中的參數(shù)的方式如下。

func main() {
    //Default返回一個默認(rèn)的路由引擎
    r := gin.Default()
    r.GET("/user/search/:username/:address", func(c *gin.Context) {
        username := c.Param("username")
        address := c.Param("address")
        //輸出json結(jié)果給調(diào)用方
        c.JSON(http.StatusOK, gin.H{
            "message":  "ok",
            "username": username,
            "address":  address,
        })
    })

    r.Run(":8080")
}

6.3 取JSON參數(shù)

當(dāng)前端請求的數(shù)據(jù)通過JSON提交時,例如向/json發(fā)送一個JSON格式的POST請求,則獲取請求參數(shù)的方式如下:

package main

import (
    "encoding/json"
    "fmt"
    "github.com/gin-gonic/gin"
    "net/http"
)

func main() {
    r := gin.Default()
    r.POST("/json", func(c *gin.Context) {
        // 注意:下面為了舉例子方便,暫時忽略了錯誤處理
        b, _ := c.GetRawData() // 從c.Request.Body讀取請求數(shù)據(jù)
        fmt.Printf("raw data: %s\n", string(b))
        // 定義map或結(jié)構(gòu)體
        var m map[string]interface{}
        // 反序列化
        _ = json.Unmarshal(b, &m)

        c.JSON(http.StatusOK, m)
    })
    r.Run(":8080")
}

七、路由組

在Gin框架中,路由組是一種用于組織和管理路由的機制。路由組可以幫助開發(fā)者更好地組織代碼,提高可讀性,并且能夠?qū)σ唤M路由應(yīng)用相同的中間件。以下是關(guān)于路由組的介紹:

7.1 普通路由

普通路由是指直接注冊在Gin引擎上的路由,這些路由沒有被分組,是獨立存在的。下面是一個普通路由的簡單例子:

package main

import (
    "github.com/gin-gonic/gin"
    "net/http"
)

func main() {
    router := gin.Default()

    router.GET("/hello", func(c *gin.Context) {
        c.String(http.StatusOK, "Hello, Gin!")
    })

    router.GET("/world", func(c *gin.Context) {
        c.String(http.StatusOK, "World, Gin!")
    })

    router.Run(":8080")
}

上述例子中,/hello/world 是兩個獨立的普通路由。

7.2 路由組

路由組通過Group方法創(chuàng)建,可以將一組相關(guān)的路由放到同一個路由組中。通過路由組,可以更好地組織代碼和應(yīng)用中間件。以下是一個簡單的路由組示例:

package main

import (
    "github.com/gin-gonic/gin"
    "net/http"
)

func main() {
    router := gin.Default()

    // 創(chuàng)建一個路由組
    apiGroup := router.Group("/api")

    // 在路由組中注冊路由
    apiGroup.GET("/users", func(c *gin.Context) {
        c.String(http.StatusOK, "Get Users")
    })

    apiGroup.POST("/users", func(c *gin.Context) {
        c.String(http.StatusOK, "Create User")
    })

    router.Run(":8080")
}

上述例子中,/api 是一個路由組,包含了兩個路由 /users(GET和POST)。這樣,相同業(yè)務(wù)功能的路由被組織在一起,提高了代碼的可讀性和可維護(hù)性。

八、重定向

8.1 HTTP重定向

HTTP 重定向很容易。 內(nèi)部、外部重定向均支持。

r.GET("/test", func(c *gin.Context) {
    c.Redirect(http.StatusMovedPermanently, "http://www.sogo.com/")
})

8.2 路由重定向

路由重定向,使用HandleContext

r.GET("/test", func(c *gin.Context) {
    // 指定重定向的URL
    c.Request.URL.Path = "/test2"
    r.HandleContext(c)
})
r.GET("/test2", func(c *gin.Context) {
    c.JSON(http.StatusOK, gin.H{"hello": "world"})
})

九、請求參數(shù)綁定

在Gin框架中,請求參數(shù)綁定是一種常見的操作,它允許你從HTTP請求中提取參數(shù)并將其綁定到Go語言結(jié)構(gòu)體中。這樣可以更方便地處理請求數(shù)據(jù)。以下是關(guān)于請求參數(shù)綁定的一些建議和示例:

9.1 獲取查詢參數(shù)

你可以使用c.Queryc.DefaultQuery方法來獲取URL中的查詢參數(shù)。

package main

import (
    "github.com/gin-gonic/gin"
    "net/http"
)

type QueryParams struct {
    Name  string `form:"name"`
    Age   int    `form:"age"`
}

func main() {
    router := gin.Default()

    router.GET("/user", func(c *gin.Context) {
        var queryParams QueryParams

        // 使用 c.ShouldBindQuery 綁定查詢參數(shù)到結(jié)構(gòu)體
        if err := c.ShouldBindQuery(&queryParams); err == nil {
            c.JSON(http.StatusOK, gin.H{
                "name": queryParams.Name,
                "age":  queryParams.Age,
            })
        } else {
            c.String(http.StatusBadRequest, "參數(shù)綁定失敗")
        }
    })

    router.Run(":8080")
}

上述例子中,通過c.ShouldBindQuery將查詢參數(shù)綁定到QueryParams結(jié)構(gòu)體中,然后使用這個結(jié)構(gòu)體處理請求。

9.2 獲取表單數(shù)據(jù)

使用c.ShouldBindc.ShouldBindJSON方法可以將POST請求的表單數(shù)據(jù)或JSON數(shù)據(jù)綁定到結(jié)構(gòu)體中。

package main

import (
    "github.com/gin-gonic/gin"
    "net/http"
)

type FormData struct {
    Name string `form:"name"`
    Age  int    `form:"age"`
}

func main() {
    router := gin.Default()

    router.POST("/user", func(c *gin.Context) {
        var formData FormData

        // 使用 c.ShouldBind 綁定表單數(shù)據(jù)到結(jié)構(gòu)體
        if err := c.ShouldBind(&formData); err == nil {
            c.JSON(http.StatusOK, gin.H{
                "name": formData.Name,
                "age":  formData.Age,
            })
        } else {
            c.String(http.StatusBadRequest, "參數(shù)綁定失敗")
        }
    })

    router.Run(":8080")
}

在上述例子中,c.ShouldBind將表單數(shù)據(jù)綁定到FormData結(jié)構(gòu)體中。

十、小黃書起步:Web 接口之用戶模塊設(shè)計

10.1 用戶模塊分析

我們現(xiàn)在要設(shè)計一個用戶模塊,對于一個用戶模塊來說,最先要設(shè)計的接口就是:注冊和登錄。而后要考慮提供:編輯和查看用戶信息。同樣的需求我們按照RESTful API設(shè)計如下:

請求方法 URL 含義
GET /users/profile 查詢用戶信息
POST /users/signup 用戶登錄
POST /users/login 用戶注冊
POST /users/edit 編輯用戶信息

首先,我們創(chuàng)建一個webook目錄,并且初始化go mod

mkdir webook
go mod init webook

10.2 目錄結(jié)構(gòu)

項目目錄結(jié)構(gòu)如圖:

在 webook 頂級目錄下有:

  • main 文件,用于啟動 webook。
  • 一個 internal 包,里面放著的就是我們所有的業(yè)務(wù) 代碼。
  • 一個 pkg 包,這是我們用于存放公共庫和包。

10.3 Handler 的用途

接著我們在user.go 中直接定義了一個 UserHandler,然后將所有 和用戶有關(guān)的路由都定義在了這個 Handler 上,同時,也定義了一個 RegisterRoutes 的方法,用來注冊路由。這里用定義在UserHandler 上的方法來作為對應(yīng)路由的處理邏輯。

10.4 用分組路由來簡化注冊

你可以注意到,就是我們所有的路由都有 /users 這個前綴,要是手一抖就有可能寫錯,這時候可以考慮使用 Gin 的分組路由功能,修改后如下:

image-20240104195442246

10.5 接收請求數(shù)據(jù):接收請求結(jié)構(gòu)體

一般來說,我們都是定義一個結(jié)構(gòu)體來接受數(shù)據(jù)。這里我們使用了方法內(nèi)部類 SignUpRequest 來接收數(shù)據(jù)。

10.6 接收請求數(shù)據(jù):Bind 方法

Bind 方法是 Gin 里面最常用的用于接收請求的方法。

Bind 方法會根據(jù) HTTP 請求的 Content-Type 來決定怎么處理。

比如我們的請求是 JSON 格式,Content-Typeapplication/json,那么 Gin 就會使用 JSON 來反序列化。

如果 Bind 方法發(fā)現(xiàn)輸入有問題,它就會直接返回一個錯誤響應(yīng)到前端。

10.7 校驗請求:正則表達(dá)式

在我們這個注冊的業(yè)務(wù)里面,校驗分為如下:

  • 郵箱需要符合一定的格式:也就是賬號這里,必須是一個合法的郵箱。
  • 密碼和確認(rèn)密碼需要相等:這是為了確保用戶沒有輸錯。
  • 密碼需要符合一定的規(guī)律:要求用戶輸入的密碼必須不少于八位,必須要包含數(shù)字、特殊字符。

綜上所述,我們用正則表達(dá)式來校驗請求,正則表達(dá)式是一種用于匹配和操作文本的強大工 具,它是由一系列字符和特殊字符組成的模式,用 于描述要匹配的文本模式。正則表達(dá)式可以在文本中查找、替換、提取和驗證 特定的模式。代碼如圖:

10.8 校驗請求:預(yù)編譯正則表達(dá)式

我們可以預(yù)編譯正則表達(dá)式來提高校驗速度。

10.9 校驗請求:Go 正則表達(dá)式不支持部分語法

前面我們用的是官方自帶的,但是 Go 自帶的正 則表達(dá)式不支持一些語法,比如說我這里想要用 的表達(dá)式:^(?=.*[A-Za-z])(?=.*\d)(?=.*[$@$!%*#?&])[A-Za-z\d$@$!%*#?&]{8,}$

類似于 ?=.這種就不支持。所以我們換用另外一個開源的正則表達(dá)式匹配 庫:github.com/dlclark/regexp2

10.10 校驗請求:全部校驗

整體的校驗如圖,注意我們區(qū)分了不同的錯誤,返回了不同的錯誤提示。

最后,完整代碼如下:

user.go 文件

package web

import (
    "fmt"
    regexp "github.com/dlclark/regexp2"
    "github.com/gin-gonic/gin"
    "net/http"
)

type UserHandler struct {
    emailExp    *regexp.Regexp
    passwordExp *regexp.Regexp
}

func NewUserHandler() *UserHandler {
    const (
        emailRegexPattern    = "^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$"
        passwordRegexPattern = `^(?=.*[A-Za-z])(?=.*\d)(?=.*[$@$!%*#?&])[A-Za-z\d$@$!%*#?&]{8,}$`
    )
    emailExp := regexp.MustCompile(emailRegexPattern, regexp.None)
    passwordExp := regexp.MustCompile(passwordRegexPattern, regexp.None)
    return &UserHandler{
        emailExp:    emailExp,
        passwordExp: passwordExp,
    }
}

func (u *UserHandler) RegisterRoutes(server *gin.Engine) {
    ug := server.Group("/user")   //ug is user group
    ug.GET("/profile", u.Profile) // 查詢用戶信息接口
    ug.POST("/signup", u.SignUp)  // 注冊接口
    ug.POST("/login", u.Login)    // 登錄接口
    ug.POST("/logout", u.Logout)  // 登出接口
    ug.POST("/edit", u.Edit)      // 修改用戶信息接口

}

func (u *UserHandler) RegisterRoutesV1(ug *gin.RouterGroup) {
    ug.GET("/profile", u.Profile) // 查詢用戶信息接口
    ug.POST("/signup", u.SignUp)  // 注冊接口
    ug.POST("/login", u.Login)    // 登錄接口
    ug.POST("/logout", u.Logout)  // 登出接口
    ug.POST("/edit", u.Edit)      // 修改用戶信息接口

}
func (u *UserHandler) Profile(ctx *gin.Context) {
}
func (u *UserHandler) SignUp(ctx *gin.Context) {
    type SignUpRequest struct {
        Email           string `json:"email"`
        Password        string `json:"password"`
        ConfirmPassword string `json:"confirmPassword"`
    }
    var request SignUpRequest
    // 如果 Bind 方法發(fā)現(xiàn)輸入有問題,它就會直接返回一 個錯誤響應(yīng)到前端。
    if err := ctx.Bind(&request); err != nil {
        return
    }

    ok, err := u.emailExp.MatchString(request.Email)
    if err != nil {
        ctx.String(http.StatusOK, "系統(tǒng)錯誤")
        return
    }
    if !ok {
        ctx.String(http.StatusOK, "郵箱格式錯誤")
        return
    }
    ok, err = u.passwordExp.MatchString(request.Password)
    if err != nil {
        ctx.String(http.StatusOK, "系統(tǒng)錯誤")
        return
    }
    if !ok {
        ctx.String(http.StatusOK, "密碼必須包含至少一個數(shù)字、一個字母、一個特殊字符,并且長度至少為8位")
        return
    }
    if request.Password != request.ConfirmPassword {
        ctx.String(http.StatusOK, "兩次密碼不一致")
        return
    }
    ctx.String(http.StatusOK, "注冊成功")
    fmt.Printf("請求體為:%v", request)
}
func (u *UserHandler) Login(ctx *gin.Context) {

}

func (u *UserHandler) Logout(ctx *gin.Context) {

}
func (u *UserHandler) Edit(ctx *gin.Context) {

}

main.go 文件:

package main

import (
    "github.com/gin-gonic/gin"
    "strings"
    "time"
    "webook/internal/web"
)

func main() {
    server := gin.Default()
    u := web.NewUserHandler()
    u.RegisterRoutes(server)
    //ug := server.Group("/user/v1") //ug is user group
    //c.RegisterRoutesV1(ug)
    server.Run(":8080")
}

最后,我們通過postman 請求接口:http://127.0.0.1:8080/user/signup/

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Restful是一種規(guī)范,把一切都看作是資源,前后端進(jìn)行分離。 RESTful 10條規(guī)范 協(xié)議API與用戶的通信...
    Ginta閱讀 4,120評論 0 1
  • title: Restful API 設(shè)計學(xué)習(xí)date: 2021/03/30 10:15 一、協(xié)議 API與用戶...
    想54256閱讀 436評論 0 1
  • API定義規(guī)范 本規(guī)范設(shè)計基于如下使用場景: 請求頻率不是非常高:如果產(chǎn)品的使用周期內(nèi)請求頻率非常高,建議使用雙通...
    有涯逐無涯閱讀 2,927評論 0 6
  • 前言 REST是什么2.1、起源2.2、REST架構(gòu)的標(biāo)志2.3、超媒體(hypermedia)2.4、REST誤...
    寒江雪_獨釣閱讀 1,408評論 0 7
  • restful(表者征狀態(tài)轉(zhuǎn)移,面向資源編程)----------------------------------...
    優(yōu)秀的人A閱讀 697評論 0 0

友情鏈接更多精彩內(nèi)容