iT邦幫忙

2024 iThome 鐵人賽

DAY 19
0
Modern Web

Go 快 Go 高效: 從基礎語法到現代Web應用開發系列 第 19

【Day19】RESTful API 設計 I | 讀取方式 (Get) 介紹

  • 分享至 

  • xImage
  •  

前言

上一篇我們已經把基礎的程式架構給實現了,那我們今天就來認識要如何實作查詢的方法吧


序列化(Serialization)

序列化 是指將內存中的數據結構(如結構體、對象)轉換為可存儲或傳輸的格式(如 JSON、XML、二進制)。在 API 開發中,序列化通常用於將服務器端的數據轉換為 JSON 格式,便於通過 HTTP 回應發送給客戶端。


Repository 實現方法

首先,我們需要在 repositories 包中實現用於查詢單個用戶和所有用戶的方法。

  • GetByID
func GetByID(id uint) (*models.User, error) {
	var user models.User
	result := database.DB.Context.First(&user, id)
	if result.Error != nil {
		return nil, result.Error
	}
	return &user, nil
}
  • database.DB.Context.First(&user, id): 使用 GORM 的 First 方法根據提供的 id 查找第一條匹配的 User 記錄,並將結果存入 user 變數中。如果找不到記錄,會返回一個錯誤。
  • GetAll
func GetAll() ([]models.User, error) {
	var users []models.User
	result := database.DB.Context.Find(&users)
	if result.Error != nil {
		return nil, result.Error
	}
	return users, nil
}
  • database.DB.Context.Find(&users):使用 GORM 的 Find 方法查詢資料庫中的所有 User 記錄,並將結果存入 users 切片中。如果查詢過程中出現錯誤,會返回該錯誤。

Handle 實現方法

接下來,我們將在 handler 包中實現 GetHandleGetAllHandle 這兩個處理函數,這些函數將處理 HTTP 請求,調用相應的 repository 方法,並返回適當的 HTTP 回應。

  • GetHandle
func GetHandle(context *gin.Context) {
	// 從 URL 參數中獲取 ID
	idParam := context.Param("id")
	id, err := strconv.Atoi(idParam)
	if err != nil {
		context.JSON(http.StatusBadRequest, gin.H{"error": "Invalid user ID"})
		return
	}

	// 調用 repository 獲取用戶
	user, err := repositories.GetByID(uint(id))
	if err != nil {
		// 判斷是否為記錄未找到錯誤
		if err.Error() == "record not found" {
			context.JSON(http.StatusNotFound, gin.H{"error": "User not found"})
		} else {
			context.JSON(http.StatusInternalServerError, gin.H{"error": "Internal server error"})
		}
		return
	}

	// 返回用戶資料
	context.JSON(http.StatusOK, user)
}
  • context.Param("id"):從 URL 路徑中提取名為 id 的路由參數,用於識別特定的用戶。
  • context.JSON(http.StatusBadRequest, gin.H{"error": "Invalid user ID"}):如果 id 轉換失敗,返回 400 Bad Request 狀態碼和自定義的錯誤訊息,表示客戶端發送的請求中包含無效的用戶 ID。
    那我們的context.JSON 就是用來序列化回應資料,我們將 user 結構體序列化為 JSON,並返回狀態碼。
  • GetAllHandle
func GetAllHandle(context *gin.Context) {
	// 調用 repository 獲取所有用戶
	users, err := repositories.GetAll()
	if err != nil {
		context.JSON(http.StatusInternalServerError, gin.H{"error": "Internal server error"})
		return
	}

	// 返回用戶列表
	context.JSON(http.StatusOK, users)
}

注意事項

特性 Param(路由參數) Query(查詢參數)
定義方式 URL 路徑的一部分,例如 /user/:id URL 的查詢部分,例如 /users?page=1
用途 標識特定資源,如單一用戶 傳遞輔助信息,如過濾、排序、分頁等
獲取方式 context.Param("key") context.Query("key")context.DefaultQuery("key", "default")
適用場景 CRUD 操作中的資源標識,如 GET /user/1 API 查詢參數,如 GET /users?page=1&limit=10

API 測試

Postman

  • GetHandle
    https://ithelp.ithome.com.tw/upload/images/20240927/20161850PIcBPUbD2L.png
  • GetAllHandle
    https://ithelp.ithome.com.tw/upload/images/20240927/20161850JUNLTZ9rPO.png

Apifox

  • GetHandle
    https://ithelp.ithome.com.tw/upload/images/20240927/20161850MryG2quMOC.png
  • GetAllHandle
    https://ithelp.ithome.com.tw/upload/images/20240927/20161850WzcH0FeQY7.png

總結

在本篇文章中,我們深入探討了如何在 Gin 框架中實作查詢功能,和我們該如何去檢查我們寫好的 api,那我們明天再介紹如何實作修改的部分。


上一篇
【Day18】輕量 Web 框架 | 透過 Gin + router 來建構 RESTful API
下一篇
【Day20】RESTful API 設計 II | 寫入方式 (Create、Updata、Delete) 介紹
系列文
Go 快 Go 高效: 從基礎語法到現代Web應用開發20
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言