大量更新
This commit is contained in:
13
91-HarnessEngineering/1-API自动更新Postman/1-Go项目自动更新Postman.md
Normal file
13
91-HarnessEngineering/1-API自动更新Postman/1-Go项目自动更新Postman.md
Normal file
@@ -0,0 +1,13 @@
|
||||
我有Golang的代码,我需要实现的核心目标是,每次代码提交之后,能够自动将我增量更新的API发送给 Postman,然后更新到Postman collection中,最终形成自动化API维护的流程
|
||||
|
||||
基本情况说明:
|
||||
1. Windows环境Go开发环境
|
||||
2. Windows运行Postman
|
||||
3. Golang使用的是GIN框架
|
||||
|
||||
自己的方案设想
|
||||
1. 通过Codex安装Postman的MCP Server,将增量的API接口同步到Postman的Collection
|
||||
2. 使用Go代码直接生成的OpenAPI,通过openapi-to-postmanv2工具转换成Postman的Collection
|
||||
3. 通过大模型的SKILL控制Postman的API,直接更新Collection
|
||||
|
||||
请你根据实际情况,分析以上三种方案的可行性,可以不局限于上述的方案,可以给出更加优秀的方案,并给出最合适的方案,包括具体的实施步骤和代码示例
|
||||
215
91-HarnessEngineering/1-API自动更新Postman/2-Go项目同步实现方案.md
Normal file
215
91-HarnessEngineering/1-API自动更新Postman/2-Go项目同步实现方案.md
Normal file
@@ -0,0 +1,215 @@
|
||||
## 基本信息如下
|
||||
1. Postman API KEY: PMAK-6a3cc4b60d07e1000174ede8-e51652fd3ba3f4a2895f1386a8b317ebf1
|
||||
2. collection uid: 15340181-95b85065-2cf9-4ebe-bde2-e76fbfdeeea9
|
||||
|
||||
|
||||
**推荐方案是:方案二(swag + openapi-to-postmanv2 + Git pre-commit hook + Postman API 自动推送)的完整自动化流水线**,
|
||||
|
||||
***
|
||||
|
||||
## 三种方案可行性分析
|
||||
|
||||
| 维度 | 方案一:Postman MCP Server | 方案二:OpenAPI 转换流水线 | 方案三:大模型控制 Postman API |
|
||||
|---|---|---|---|
|
||||
| **稳定性** | ⚠️ MCP 协议仍在快速变化,Postman MCP Server 尚不成熟 | ✅ 工具链稳定,swag+openapi-to-postmanv2 均为生产可用 | ❌ 大模型调用有延迟、不确定性,不适合自动化 CI |
|
||||
| **Gin 原生支持** | ❌ 无法感知路由,需手动描述 | ✅ swag 直接解析 Gin 路由注解,完全自动化 | ❌ 需要额外描述路由结构 |
|
||||
| **增量同步** | ⚠️ 依赖 MCP 协议实现,Collection 合并逻辑不透明 | ✅ Postman PUT API 覆盖 Collection,配合 folderStrategy=Tags 保持结构 | ❌ 无法保证增量一致性 |
|
||||
| **Windows 兼容** | ❌ Codex 在 Windows 下配置复杂 | ✅ npm + swag CLI 在 Windows 完全支持 | ⚠️ 依赖 API 密钥,可行但复杂 |
|
||||
| **离线可用** | ❌ 依赖 Codex 云端服务 | ✅ 除推送 Postman API 外完全本地 | ❌ 必须联网 |
|
||||
|
||||
***
|
||||
|
||||
## 推荐方案:OpenAPI 自动化流水线
|
||||
|
||||
整体流程为:
|
||||
|
||||
```
|
||||
git commit
|
||||
↓ pre-commit hook
|
||||
swag init (生成 swagger.json)
|
||||
↓
|
||||
openapi2postmanv2 (转换为 collection.json)
|
||||
↓
|
||||
curl PUT Postman API (推送到 Postman Collection)
|
||||
↓
|
||||
git commit 完成
|
||||
```
|
||||
|
||||
***
|
||||
|
||||
## 具体实施步骤
|
||||
|
||||
### Step 1:安装依赖工具
|
||||
|
||||
```bash
|
||||
# 安装 swag(Go OpenAPI 注解生成器)
|
||||
go install github.com/swaggo/swag/cmd/swag@latest
|
||||
|
||||
# 安装 Gin swagger 中间件
|
||||
go get -u github.com/swaggo/gin-swagger
|
||||
go get -u github.com/swaggo/files
|
||||
|
||||
# 安装 openapi-to-postmanv2(需要 Node.js)
|
||||
npm install -g openapi-to-postmanv2
|
||||
```
|
||||
|
||||
### Step 2:在 Gin 路由上添加 swag 注解
|
||||
|
||||
在 `main.go` 中添加全局文档注解 : [medium](https://medium.com/@feldy7k/how-to-create-a-dynamic-swagger-ui-for-golang-api-with-gin-5b85eaa248b3)
|
||||
|
||||
```go
|
||||
// @title My API
|
||||
// @version 1.0
|
||||
// @description API 文档
|
||||
// @host localhost:8080
|
||||
// @BasePath /api/v1
|
||||
package main
|
||||
|
||||
import (
|
||||
_ "your-project/docs" // swag 生成的 docs 包
|
||||
ginSwagger "github.com/swaggo/gin-swagger"
|
||||
swaggerFiles "github.com/swaggo/files"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func main() {
|
||||
r := gin.Default()
|
||||
r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
|
||||
// ... 路由注册
|
||||
r.Run()
|
||||
}
|
||||
```
|
||||
|
||||
在具体 Handler 函数上添加接口注解:
|
||||
|
||||
```go
|
||||
// GetUser 获取用户信息
|
||||
// @Summary 获取用户
|
||||
// @Description 通过 ID 获取用户详情
|
||||
// @Tags users
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param id path int true "User ID"
|
||||
// @Success 200 {object} UserResponse
|
||||
// @Failure 404 {object} ErrorResponse
|
||||
// @Router /users/{id} [get]
|
||||
func GetUser(c *gin.Context) {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Step 3:配置 Git pre-commit hook
|
||||
|
||||
在项目根目录创建 `.git/hooks/pre-commit` 文件(Windows 下可创建 `pre-commit` 无扩展名文件): [richardswinbank](https://richardswinbank.net/git/hooks)
|
||||
|
||||
```bash
|
||||
#!/bin/sh
|
||||
# pre-commit: 自动生成 OpenAPI -> 转换 -> 推送 Postman
|
||||
|
||||
set -e
|
||||
|
||||
echo "[hook] 正在生成 swagger 文档..."
|
||||
swag init --generalInfo cmd/main.go --output docs
|
||||
|
||||
echo "[hook] 正在转换为 Postman Collection..."
|
||||
openapi2postmanv2 -s docs/swagger.json \
|
||||
-o docs/postman_collection.json \
|
||||
-p \
|
||||
-O folderStrategy=Tags,includeAuthInfoInExample=true
|
||||
|
||||
echo "[hook] 正在推送到 Postman..."
|
||||
# POSTMAN_API_KEY 和 POSTMAN_COLLECTION_UID 通过环境变量注入
|
||||
node scripts/update-postman.js
|
||||
|
||||
# 将生成的文档文件加入本次提交
|
||||
git add docs/swagger.json docs/swagger.yaml docs/postman_collection.json
|
||||
echo "[hook] API 文档已自动更新并加入提交"
|
||||
```
|
||||
|
||||
### Step 4:创建 Postman 推送脚本
|
||||
|
||||
创建 `scripts/update-postman.js` : [community.postman](https://community.postman.com/t/automatically-sync-swagger-apis-with-postman-when-bitbucket-files-are-changed/89229)
|
||||
|
||||
```javascript
|
||||
const fs = require('fs');
|
||||
const https = require('https');
|
||||
|
||||
const POSTMAN_API_KEY = process.env.POSTMAN_API_KEY;
|
||||
const COLLECTION_UID = process.env.POSTMAN_COLLECTION_UID;
|
||||
|
||||
if (!POSTMAN_API_KEY || !COLLECTION_UID) {
|
||||
console.error('缺少环境变量: POSTMAN_API_KEY 或 POSTMAN_COLLECTION_UID');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const collectionData = JSON.parse(
|
||||
fs.readFileSync('./docs/postman_collection.json', 'utf8')
|
||||
);
|
||||
|
||||
// Postman API 要求 collection 包装在 { collection: ... } 中
|
||||
const body = JSON.stringify({ collection: collectionData });
|
||||
|
||||
const options = {
|
||||
hostname: 'api.getpostman.com',
|
||||
path: `/collections/${COLLECTION_UID}`,
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-Api-Key': POSTMAN_API_KEY,
|
||||
'Content-Length': Buffer.byteLength(body)
|
||||
}
|
||||
};
|
||||
|
||||
const req = https.request(options, (res) => {
|
||||
let data = '';
|
||||
res.on('data', chunk => data += chunk);
|
||||
res.on('end', () => {
|
||||
const result = JSON.parse(data);
|
||||
if (res.statusCode === 200) {
|
||||
console.log(`✅ Postman Collection 更新成功: ${result.collection?.name}`);
|
||||
} else {
|
||||
console.error(`❌ 更新失败 (${res.statusCode}):`, data);
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
req.on('error', (e) => { console.error('请求错误:', e); process.exit(1); });
|
||||
req.write(body);
|
||||
req.end();
|
||||
```
|
||||
|
||||
### Step 5:配置环境变量(Windows)
|
||||
|
||||
```powershell
|
||||
# 在 PowerShell 中设置用户级环境变量(持久化)
|
||||
[System.Environment]::SetEnvironmentVariable(
|
||||
"POSTMAN_API_KEY", "your_api_key_here", "User"
|
||||
)
|
||||
[System.Environment]::SetEnvironmentVariable(
|
||||
"POSTMAN_COLLECTION_UID", "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "User"
|
||||
)
|
||||
```
|
||||
|
||||
**获取 Collection UID** 的方法:在 Postman 桌面端右键点击 Collection → **Copy link** 或 **Info**,URL 中的 UUID 即为 UID。**获取 API Key**:Postman → 头像 → Settings → API Keys → Generate API Key 。 [community.postman](https://community.postman.com/t/update-a-collection-using-postman-api/906)
|
||||
|
||||
***
|
||||
|
||||
## 进阶优化:仅在 .go 文件变更时触发
|
||||
|
||||
将 `pre-commit` 脚本中的触发逻辑改为仅当有 Go 文件变更时执行,避免无意义的推送:
|
||||
|
||||
```bash
|
||||
#!/bin/sh
|
||||
# 检查是否有 .go 文件变更
|
||||
GO_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep '\.go$')
|
||||
|
||||
if [ -z "$GO_FILES" ]; then
|
||||
echo "[hook] 无 .go 文件变更,跳过 API 文档更新"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# ... 后续 swag init、转换、推送逻辑
|
||||
```
|
||||
|
||||
***
|
||||
Reference in New Issue
Block a user