iT邦幫忙

2025 iThome 鐵人賽

DAY 18
0
Software Development

Go Clean Architecture API 開發全攻略系列 第 18

API 文件:使用程式產生 API 文件,讓前後端協作更順暢

  • 分享至 

  • xImage
  •  

在現代軟體開發中,API(應用程式介面)是前後端溝通的橋樑。隨著專案規模的擴大,手動維護 API 文件變得越來越困難且容易出錯。
為了解決這個問題,採用自動化工具來生成 API 文件,這不僅提高了效率,還確保了文件的準確性和一致性。

選擇的方向

我們選擇使用自動化工具來生成 API 文件,這樣可以減少手動維護的工作量,並確保文件與實際程式碼保持同步。
常見的工具包括 Swagger、Postman 和 Apiary 等。
這些工具能夠根據程式碼中的註解或結構自動生成 API 文件,並提供可視化的介面,方便前端開發人員查閱和測試 API。

最佳實踐

  1. 統一格式:選擇一種標準的 API 文件格式(如 OpenAPI/Swagger),確保所有團隊成員都能理解和使用。
  2. 保持文件更新:將 API 文件的生成過程納入 CI/CD 流程中,確保每次程式碼變更後文件都能自動更新。
  3. 提供範例請求和回應:在 API 文件中包含範例請求和回應,幫助前端開發人員更快理解 API 的使用方式。
  4. 使用版本控制:對 API 文件進行版本控制,確保不同版本的 API 文件能夠共存,並且方便追蹤變更歷史。

透過這些最佳實踐,開發團隊可以更輕鬆地維護 API 文件,提高前後端協作的效率。

為什麼選擇 Swagg/swag

在眾多自動化 API 文件生成工具中,我們選擇了 Swagg/swag,這是一個專為 Go 語言設計的工具,具有以下優點:

  • 簡單易用:只需在程式碼中添加註解,即可自動生成 API 文件,降低了學習曲線。
  • 豐富的功能:支持多種輸出格式(如 JSON、YAML),並提供可視化的 Swagger UI,方便前端開發人員查閱和測試 API。

也是有一些缺點,例如:

只支援 openapi 2.0,無法使用 openapi 3.0 的新功能。
在有 support openapi 3.0 的工具出現前,也就只能這樣使用了。
ex: 無法指定使用 Bearer token 的 security scheme。

實作

第一部分 專案說明及相關設定

// main.go

//	@title					Go Clean Architecture API
//	@version				0.0.1
//	@description 		This is Go Clean Architecture API
//	@termsOfService
//	@host 					go-clean-architecture.xxxx.com

//	@securityDefinitions.apikey Bearer
//	@in header
//	@name Authorization
//	@description Type "Bearer" followed by a space and JWT token.

//	@BasePath	/
//	@schemes	https
  • 設定說明:
    • @title:API 的標題

    • @version:API 的版本

    • @description:API 的描述

    • @termsOfService:API 的服務條款

    • @host:API 的主機名稱

    • @securityDefinitions.apikey: 定義 API 的安全性方案,API 端就只需要指定是否使用這個方案

    • @in:指定安全性方案的位置(如 header、query)

    • @name:指定安全性方案的名稱

    • @description:描述安全性方案的使用方式

    • @BasePath:API 的基本路徑

    • @schemes:API 支援的通訊協定

第二部分 API 註解

我們以先前已經實作的 register API 為例,說明如何添加註解來生成 API 文件。

// internal/controller/user.go

// @Summary			Register
// @Description	User Registration
// @Tags				User
// @Accept			json
// @Produce			json
// @Param				request	body		request.Register	true	"User Registration Info"
// @Success			200		{object}	GeneralSuccessResponse{data=string}	"Returns access token"
// @Failure			400		{object}	GeneralErrorResponse					"Bad Request - Invalid input data"
// @Failure			409		{object}	GeneralErrorResponse					"Conflict - Email already registered"
// @Failure			500		{object}	GeneralErrorResponse					"Internal Server Error"
// @Security		Bearer
// @Router			/api/user/register [post]
func (u *UserController) Register(usecase *register.UseCase) gin.HandlerFunc {
  • 設定說明:
    • @Summary:API 的簡短描述
    • @Description:API 的詳細描述
    • @Tags:API 所屬的分類標籤
    • @Accept:API 支援的請求格式(如 json、xml)
    • @Produce:API 支援的回應格式(如 json、xml)
    • @Param:API 的參數說明,包括參數名稱、位置(如 body、query)、資料型別、是否必填及描述
    • @Success:成功回應的狀態碼及資料型別說明
    • @Failure:失敗回應的狀態碼及資料型別說明
    • @Security:指定 API 使用的安全性方案
    • @Router:API 的路由及 HTTP 方法

這裡偷渡了一點點小修改,我們在 controller 中加上了標準的 response struct,讓 API 文件可以更清楚地描述回應格式。
ex: GeneralSuccessResponseGeneralErrorResponse

第三部分 生成 API 文件

我們一樣把指令放在 Makefile 裡面,方便日後使用。

# Variables
DockerImageNameSwaggerGenerate='ghcr.io/swaggo/swag:v1.16.6'

## ==============================================================================
# Swagger
# ==============================================================================

.PHONY: swaggerGenerateDoc

swaggerGenerateDoc: ## Generate API Swagger documentation
	@docker run --rm -v $(pes_parent_dir):/code ${DockerImageNameSwaggerGenerate} init -o ./docs/api --ot json -g cmd/api/main.go

第四部分 提供 API 文件

最後,我們需要在專案中提供生成的 API 文件,讓前端開發人員可以方便地查閱和測試 API。

我們可以使用外部提供的 UI 來展示這些文件。

外部 UI 有許多選擇,這裡我們使用 Rapidoc
然後建立一個 swagger.html 檔案,內容大致如下:

<head>
  <meta charset="utf-8"> <!-- Important: rapi-doc uses utf8 characters -->
  <script type="module" src="https://rapidocweb.com/rapidoc-min.js"></script>
</head>

<body>
  <rapi-doc spec-url="swagger.json" show-header="false" show-method-in-nav-bar="as-colored-block"
    sort-tags="true" schema-description-expanded="true" render-style="view" font-size="largest">
  </rapi-doc>
</body>
  • spec-url:指定 API 文件的路徑,這裡我們使用 swagger.json,這是我們在上一個步驟中生成的文件。
  • 其他屬性:可以根據需求調整 RapiDoc 的顯示方式,如是否顯示標頭、方法欄位的樣式、標籤排序等。RapiDoc

接著,我們需要在程式中提供這些靜態檔案,並且設定基本的認證機制。

import (
  "github.com/gin-gonic/gin"
  "github.com/nick6969/go-clean-project/internal/application"
)

func registerRootRoutes(r gin.IRouter, app *application.Application) {
  ...

  auth := gin.BasicAuth(gin.Accounts{
    app.Config.APIDocAuth.UserName: app.Config.APIDocAuth.Password,
  })

  apiGroup := r.Group("", auth)
  staticFile(apiGroup, app.Embed.APIDoc, "swagger", "swagger.html", "text/html", 86400)
  staticFile(apiGroup, app.Embed.APIDoc, "swagger.json", "swagger.json", "application/json", 0)
}
  • 認證說明:
    • 使用 Basic Auth 來保護 API 文件,防止未授權的訪問
    • 認證資訊從應用程式配置中讀取,確保安全性

這樣,前端開發人員只需要訪問 /swagger 路徑,就可以看到完整的 API 文件,並且可以使用 UI 來測試 API。

總結

通過使用自動化工具生成 API 文件,我們大大提高了前後端協作的效率,減少了手動維護文件的工作量,並確保了文件的準確性和一致性。
選擇合適的工具並遵循最佳實踐,能夠讓開發團隊更輕鬆地管理 API 文件,促進專案的順利進行。

本文添加調整的完整內容可以到 Github 觀看


上一篇
Dockerize 你的 Go 應用:使用 Docker Compose 打造一致的開發環境
下一篇
[Day 19] Domain Model 設計:定義專案最核心的商業規則
系列文
Go Clean Architecture API 開發全攻略19
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言