使用 Go 和 Gin 開發 RESTful API
本教學介紹了使用 Go 和 Gin Web 框架 (Gin) 撰寫 RESTful Web 服務 API 的基礎知識。
如果你對 Go 及其工具鏈有基本的了解,你將能從本教學中獲得最大收益。如果你是第一次接觸 Go,請參閱 教學:Go 入門 以快速了解。
Gin 簡化了許多與建構 Web 應用相關的編碼任務,包括 Web 服務。在本教學中,你將使用 Gin 來路由請求、檢索請求細節並編組回應的 JSON。
在本教學中,你將建構一個具有兩個端點的 RESTful API 伺服器。你的範例項目將是一個關於復古爵士唱片的資料儲存庫。
本教學包括以下部分:
- 設計 API 端點。
- 為程式碼建立一個資料夾。
- 建立資料。
- 撰寫處理程式以返回所有項目。
- 撰寫處理程式以加入新項目。
- 撰寫處理程式以返回特定項目。
要將其作為在 Google Cloud Shell 中完成的互動式教學,請點擊下面的按鈕。
先決條件
- Go 1.16 或更高版本的安裝。 有關安裝說明,請參閱 安裝 Go。
- 一個用於編輯程式碼的工具。 任何你擁有的文字編輯器都可以正常工作。
- 一個命令終端。 Go 在 Linux 和 Mac 上的任何終端上都能很好地工作,在 Windows 上的 PowerShell 或 cmd 上也是如此。
- curl 工具。 在 Linux 和 Mac 上,這應該已經安裝。在 Windows 上,它包含在 Windows 10 Insider build 17063 及更高版本中。對於較早的 Windows 版本,你可能需要安裝它。
設計 API 端點
你將建構一個提供對銷售復古黑膠唱片商店訪問的 API。因此,你需要提供端點,客戶端可以透過這些端點取得和加入使用者的專輯。
在開發 API 時,你通常會先設計端點。你的 API 使用者會更成功,如果端點易於理解。
以下是本教學中將建立的端點。
/albums
GET– 以 JSON 形式返回所有專輯的列表。POST– 從作為 JSON 發送的請求資料加入新專輯。
/albums/:id
GET– 透過其 ID 取得專輯,以 JSON 形式返回專輯資料。
接下來,你將為你的程式碼建立一個資料夾。
為程式碼建立一個資料夾
首先,為要撰寫的程式碼建立一個專案。
-
開啟命令提示符並切換到你的主目錄。
在 Linux 或 Mac 上:
在 Windows 上:
-
使用命令提示符,建立一個名為
web-service-gin的程式碼目錄。 -
建立一個模組來管理依賴項。
執行
go mod init命令,給它你的程式碼將位於的模組路徑。此命令建立一個
go.mod檔案,其中將列出你加入的依賴項以進行追蹤。有關使用模組路徑命名模組的更多資訊,請參閱 管理依賴項。
接下來,你將為處理資料設計資料結構。
建立資料
為了簡化本教學,你將把資料儲存在記憶體中。更典型的 API 將與資料庫互動。
請注意,將資料儲存在記憶體中意味著每次停止伺服器時專輯集合都會遺失,然後在啟動伺服器時重新建立。
撰寫程式碼
-
使用你的文字編輯器,在
web-service目錄中建立一個名為main.go的檔案。你將在此檔案中撰寫 Go 程式碼。 -
在
main.go中,在檔案頂部貼上以下套件宣告。一個獨立的程式(與函式庫相對)始終在
main套件中。 -
在套件宣告下方,貼上以下
album結構宣告。你將使用此結構在記憶體中儲存專輯資料。結構標籤如
json:"artist"指定了當結構內容序列化為 JSON 時欄位的名稱。沒有它們,JSON 將使用結構體的大寫欄位名 —— 這在 JSON 中不常見。 -
在你剛剛加入的結構宣告下方,貼上以下包含專輯資料的結構切片。
接下來,你將撰寫程式碼來實現你的第一個端點。
撰寫處理程式以返回所有項目
當客戶端在 GET /albums 處發出請求時,你想以 JSON 形式返回所有專輯。
為此,你將撰寫以下內容:
- 準備回應的邏輯
- 將請求路徑對應到你的邏輯的程式碼
注意,這與它們在執行時的順序相反,但你先加入依賴項,然後加入依賴它們的程式碼。
撰寫程式碼
-
在你上一節加入的結構體程式碼下方,貼上以下程式碼以取得專輯列表。
此
getAlbums函數從album結構體切片建立 JSON,將 JSON 寫入回應。在這段程式碼中,你:
-
撰寫一個
getAlbums函數,該函數採用gin.Context參數。注意,你可以給這個函數任何名字 —— Gin 和 Go 都不需要特定的函數名格式。gin.Context是 Gin 最重要的部分。它攜帶請求細節、驗證和序列化 JSON 等。(儘管名稱相似,但這與 Go 的內建context套件不同。) -
呼叫
Context.IndentedJSON將結構體序列化為 JSON 並加入到回應中。函數的第一個參數是你想發送給客戶端的 HTTP 狀態碼。在這裡,你傳遞了
StatusOK常數從net/http套件中,以指示200 OK。注意,你可以將
Context.IndentedJSON替換為對Context.JSON的呼叫以發送更緊湊的 JSON。在實踐中,縮進形式在除錯時更容易使用,且大小差異通常很小。
-
-
在
main.go頂部附近,緊接在albums切片宣告下方,貼上以下程式碼以將處理程式函數與端點路徑關聯。這將建立關聯,其中
getAlbums處理對/albums端點路徑的請求。在這段程式碼中,你:
-
在
main.go頂部附近,緊接在套件宣告下方,匯入你剛撰寫程式碼所需的套件。程式碼的前幾行應如下所示:
-
儲存
main.go。
執行程式碼
-
開始將 Gin 模組作為依賴項進行追蹤。
在命令列中,使用
go get將github.com/gin-gonic/gin模組加入為你的模組的依賴項。 使用點參數表示「取得目前目錄中程式碼的依賴項」。Go 解析並下載了這個依賴項,以滿足你在上一步中加入的
import宣告。 -
在包含
main.go的目錄的命令列中,執行程式碼。 使用點參數表示「執行目前目錄中的程式碼」。一旦程式碼執行,你將有一個運作的 HTTP 伺服器,你可以向其傳送請求。
-
從新的命令列視窗,使用
curl向你的運作 Web 服務發出請求。該命令應顯示你為服務提供種子的資料。
你已經啟動了一個 API!在下一節中,你將使用處理 POST 請求的程式碼建立另一個端點以加入項目。
撰寫處理程式以加入新項目
當客戶端在 /albums 處發出 POST 請求時,你想從請求本文中描述的專輯加入到現有專輯資料中。
為此,你將撰寫以下內容:
- 將新專輯加入到現有列表的邏輯
- 將
POST請求路由到你的邏輯的一小段程式碼
撰寫程式碼
-
加入程式碼以將專輯資料加入到專輯列表中。
在
import敘述之後的某個地方,貼上以下程式碼。(檔案的結尾是這段程式碼的好位置,但 Go 不強制你宣告函數的順序。)在這段程式碼中,你:
- 使用
Context.BindJSON將請求體綁定到newAlbum。 - 將 JSON 初始化的
album結構體附加到albums切片。 - 加入
201狀態碼和表示你加入的專輯的 JSON 到回應。
- 使用
-
更改你的
main函數,使其包含router.POST函數,如下所示。在這段程式碼中,你:
-
將
POST方法與/albums路徑與postAlbums函數關聯。使用 Gin,你可以將處理程式與 HTTP 方法和路徑組合關聯。透過這種方式,你可以根據客戶端使用的方法,為單一路徑分別路由請求。
-
執行程式碼
-
如果伺服器仍從上一節運作,請停止它。
-
在包含
main.go的目錄的命令列中,執行程式碼。 -
從不同的命令列視窗,使用
curl向你的運作 Web 服務發出請求。該命令應顯示加入的專輯的標頭和 JSON。
-
如上一節所述,使用
curl檢索完整的專輯列表,你可以確認新專輯是否已加入。該命令應顯示專輯列表。
在下一節中,你將撰寫程式碼來處理對特定專案的 GET 請求。
撰寫處理程式以返回特定項目
當客戶端在 GET /albums/[id] 處發出請求時,你想返回 ID 與 id 路徑參數匹配的專輯。
為此,你將撰寫:
- 加入檢索請求專輯的邏輯
- 將路徑對應到邏輯
撰寫程式碼
-
在你上一節加入的
postAlbums函數下方,貼上以下程式碼以檢索特定專輯。此
getAlbumByID函數將從請求路徑中提取 ID,然後定位匹配的專輯。在這段程式碼中,你:
-
使用
Context.Param從 URL 中檢索id路徑參數。當你將此處理程式對應到路徑時,將在路徑中包含參數的佔位符。 -
遍歷切片中的
album結構體,尋找其ID欄位值與id參數值匹配的結構體。如果找到,將該album結構體序列化為 JSON 並返回帶有200 OKHTTP 代碼的回應。如上所述,真實世界的服務可能會使用資料庫查詢來執行此查找。
-
如果未找到專輯,則使用
http.StatusNotFound返回 HTTP404錯誤。
-
-
最後,更改你的
main函數,使其包含對router.GET的新呼叫,路徑現在為/albums/:id,如下例所示。在這段程式碼中,你:
- 將
/albums/:id路徑與getAlbumByID函數關聯。在 Gin 中,路徑中冒號前導的項表示該項是路徑參數。
- 將
執行程式碼
-
如果伺服器仍從上一節執行,請先停止它。
-
在包含
main.go的目錄的命令行中,執行程式碼以啟動伺服器。 -
從不同的命令行視窗,使用
curl向你的 Web 服務發出請求。該命令應顯示你所使用 ID 的專輯 JSON 資料。如果未找到專輯,你將收到帶有錯誤訊息的 JSON。
結論
恭喜!你剛剛使用 Go 和 Gin 成功開發了一個簡單的 RESTful Web 服務。
建議後續學習方向:
- 如果你是 Go 新手,可以參考以下講述最佳實踐的文件: Effective Go 和 如何撰寫 Go 程式碼
- Go Tour 是學習 Go 基礎的優良入門教材
- 如需深入了解 Gin,請參閱 Gin Web 框架套件文件 或 Gin Web 框架官方文件
完整程式碼
本節包含本教學所建置應用程式的完整程式碼: