iT邦幫忙

2021 iThome 鐵人賽

DAY 15
0
Modern Web

fmt.Println("從零開始的Golang生活")系列 第 15

Day15 Gin's Router And RESTful API

  • 分享至 

  • xImage
  •  

What is API and HTTP?

API得全名叫做Application Programming Interface,也就是一個應用程式的街口,讓第三方可以進行開發、應用在其他用途上的溝通管道。

但首先需要先介紹一下HTTP,HTTP全名Hypertext Transfer Protocol,在該Protocol有Client、Server兩種人,舉例來說,Client指的就是我、Server指的就是Google,我在點擊Google首頁時,我就是像Google的Server傳送了這個請求,然後Google在回應所需資源給我。但為了要讓Request與Response有統一個規範,才誕生出HTTP。

舉例來說,我們搜尋了某個在Google下的網址會有以下步驟:

  • 我們在瀏覽器輸入Google網址,並點擊Enter,送出Request
  • Server收到Request,並檢查該Request的合法性
  • Server依照該Request回應相對應的Response

Response會依照該Request的合法性給出相對應的狀態碼,狀態碼也能夠大致分為以下種類:

  • 2XX: Success(成功)
  • 3XX: Redirect(重新定向)
  • 4XX: User Error(客戶端錯誤)
  • 5XX: Server Error(伺服器端錯誤)

此外,在HTTP中會有許多種不同method的請求行為,最常見的就是GET / POST / PUT /DELETE,
這些method也剛好會對應到資料庫的基本操作CRUD行為(Create, Read, Update, Delete)

What is RESTful API ?

REST全名為Representational State Transfer( 表現層狀態轉移),他是一種設計風格,而RESTful則形容以此規範設計的API,稱為RESTfuk API。

RESTful API主要由三種不同元件組成:

restful.png

  • Nouns名詞: 定義Server資源位置的URL,就像每個人家中的地址一樣。
  • Verbs動詞: 對該資源所要採取的動作。
  • Content Types資源呈現方式: API資源可以以多種方式表現,最常用的JSON,較輕也較好處理。

一般的API,可能呈現方式會是這樣:

新增資料POST /createData
獲得資料GET /getData/1
刪除資料DELETEe /deleteData/1

不同公司,不一樣的工程師,設計的名稱都會不一樣,也沒有統一的命名方式,造成在引用各家 API 時,都需要詳讀 API 文件,理解所有設計命名規則後,才可使用。

若是以RESTful API的風格開發的話:

新增資料POST    /data ,Method: POST
獲得資料GET     /data ,Method: GET
刪除資料DELETE  /data/1 ,Method: DELETE

就是用一個唯一的URL定位資源,將動作藏在HTTP的method裡面。

所以使用RESTful風格設計的API,就會有以下幾種優點以及限制:

  1. 有唯一的URL表示資源位置,並提供統一的API接口(Uniform Interface)
  2. 無狀態(Stateless)

RESTful的狀態即是HTTP的請求狀態,在一般Web服務中,Server Side與Client Side交互的資訊會存在Server Side的Session(像是登入狀態等),在Client Side再次發起請求時,Server Side會透過保存的Session去執行Request。而無狀態的意思就是Client Side會自行保存狀態,在對Server Side發出請求時,一併將其附給Server Side,Server Side並不會保存Client Side的狀態。

舉例來說,在用戶登錄系統時,Server 產生 token 紀錄 user 已登錄系統,然後把 token 還給 Client,在 Client 再次發送請求的時候,把 token 一起發給 Server,這樣 Server 就知道這一個 Client 是已經處於登錄的狀態。

  1. 更高效利用快取來提高回應速度 (Cachable),在Server中被GET過的資源在沒有變更的情況之下可以利用Cache暫存若干時間,減少request。在Client中,透過Client的cache紀錄,若向Server要求的資源版本與Cache相同,則直接對本地Cache進行調用,無需再多做一次GET。
  2. 分層系統就夠
  3. 客戶端服務器分離
  4. 乾淨且目標明確的使用HTTP Method

Routing in Gin

Using GET, POST, PUT, PATCH, DELETE and OPTIONS @ API Example

  • gin.Default():使用 gin router 預設的 middleware,包含 logger 和 recover (crash-free) 的 middleware
  • router.Run():預設是 :8080 ,可以用字串修改,例如 router.Run(":3000")
  • router.GET(): 前面的GET, POST表示方法,後面參數則是表示路徑以及接收Request執行的行為

簡單舉例如下

func main() {
    // Creates a gin router with default middleware:
    // logger and recovery (crash-free) middleware
    router := gin.Default()

    router.GET("/someGet", getting)
    router.POST("/somePost", posting)
    router.PUT("/somePut", putting)
    router.DELETE("/someDelete", deleting)
    router.PATCH("/somePatch", patching)
    router.HEAD("/someHead", head)
    router.OPTIONS("/someOptions", options)

    // By default it serves on :8080 unless a PORT environment variable was defined.
    router.Run()
    // router.Run(":3000") for a hard coded port
}

Parameters in Path

取得網址中的 params:

  • 在路由設定中
    • 使用 :<filed> 可以定義動態路由(只能匹配到 / 以前)
    • 使用 <filed> 可以定義動態路由(可以匹配到 / 以後)
  • c.Param("<field>") 可以取得網址中的參數
  • c.Fullpath() 可以取得定義的路由參數
func main() {
    router := gin.Default()

    router.GET("/user", func(c *gin.Context) {
        c.String(200, "/user")
    })

    router.GET("/user/:name", func(c *gin.Context) {
        fmt.Println(c.FullPath())  // /user/:name/
        name := c.Param("name")
        c.String(http.StatusOK, "Hello %s", name)
    })

    router.GET("/user/:name/*action", func(c *gin.Context) {
        fmt.Println(c.FullPath())   // /user/:name/*action
        name := c.Param("name")
        action := c.Param("action")
        message := name + " is " + action
        c.String(http.StatusOK, message)
    })

    router.Run(":3000")
}
  • "/user/:name": 這並不會使其匹配到/user/ 或是
  • "/user/:name/*action": 這就會使其匹配到/user/flynn/ 或是 /user/flynn/send

Summary

這章節主要介紹RESTful API以及簡單Gin Router的使用,在下個章節則會示範Gin的項目結構一般來說會長怎麼樣,如何配合middleware來建立起簡單乾淨的routing structure。


上一篇
Day14 Gin and Go Mod
下一篇
Day16 Gin's Routing Structure And Context
系列文
fmt.Println("從零開始的Golang生活")30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言