API客户端
API客户端是CWE Go库的核心组件,提供了访问CWE REST API的完整功能。
概述
APIClient
提供了一个简单而强大的接口来访问CWE数据:
- 获取CWE版本信息
- 检索弱点、类别和视图数据
- 批量获取多个CWE条目
- 内置速率限制和重试机制
创建客户端
默认客户端
go
// 创建默认配置的客户端
client := cwe.NewAPIClient()
// 输出: 创建一个具有默认配置的API客户端
默认配置包括:
- 每10秒1个请求的速率限制
- 30秒HTTP超时
- 3次重试机制
自定义客户端
go
import (
"time"
"github.com/scagogogo/cwe"
)
// 创建自定义速率限制器
limiter := cwe.NewHTTPRateLimiter(5 * time.Second)
// 创建自定义配置的客户端
client := cwe.NewAPIClientWithOptions(
"", // 使用默认API端点
30*time.Second, // HTTP超时
limiter, // 速率限制器
)
// 输出: 创建一个具有自定义配置的客户端,包括自定义基础URL、30秒超时和5秒速率限制
主要方法
获取版本信息
go
version, err := client.GetVersion()
if err != nil {
log.Fatal(err)
}
fmt.Printf("CWE版本: %s\n", version.Version)
fmt.Printf("发布日期: %s\n", version.ReleaseDate)
// 输出:
// CWE版本: 4.12
// 发布日期: 2023-01-15
获取弱点
go
// 获取单个弱点
weakness, err := client.GetWeakness("79")
if err != nil {
log.Fatal(err)
}
fmt.Printf("CWE-79: %s\n", weakness.Name)
// 输出: CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
获取类别
go
// 获取类别信息
category, err := client.GetCategory("20")
if err != nil {
log.Fatal(err)
}
fmt.Printf("类别: %s\n", category.Name)
// 输出: 类别: Improper Input Validation
获取视图
go
// 获取视图信息
view, err := client.GetView("1000")
if err != nil {
log.Fatal(err)
}
fmt.Printf("视图: %s\n", view.Name)
// 输出: 视图: Research Concepts
批量获取
go
// 获取多个CWE
ids := []string{"79", "89", "20"}
cwes, err := client.GetCWEs(ids)
if err != nil {
log.Fatal(err)
}
for id, cwe := range cwes {
fmt.Printf("CWE-%s: %s\n", id, cwe.Name)
}
text
输出:
CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')
CWE-20: Improper Input Validation
配置管理
获取和设置速率限制器
go
// 获取当前速率限制器
limiter := client.GetRateLimiter()
// 调整速率限制
limiter.SetInterval(2 * time.Second)
// 输出: 将速率限制调整为每2秒一个请求
// 或设置新的速率限制器
newLimiter := cwe.NewHTTPRateLimiter(1 * time.Second)
client.SetRateLimiter(newLimiter)
// 输出: 设置新的速率限制器,每1秒一个请求
获取和设置HTTP客户端
go
// 获取当前HTTP客户端
httpClient := client.GetHTTPClient()
// 设置新的HTTP客户端
newHTTPClient := cwe.NewHttpClient(
cwe.WithRateLimit(5),
cwe.WithMaxRetries(3),
cwe.WithRetryInterval(time.Second),
)
client.SetHTTPClient(newHTTPClient)
// 输出: 设置新的HTTP客户端,具有自定义速率限制、重试次数和重试间隔
错误处理
API客户端会返回详细的错误信息:
go
weakness, err := client.GetWeakness("invalid")
if err != nil {
switch {
case strings.Contains(err.Error(), "404"):
fmt.Println("CWE不存在")
// 输出: CWE不存在
case strings.Contains(err.Error(), "timeout"):
fmt.Println("请求超时")
// 输出: 请求超时
case strings.Contains(err.Error(), "rate limit"):
fmt.Println("请求过于频繁")
// 输出: 请求过于频繁
default:
fmt.Printf("其他错误: %v\n", err)
// 输出: 其他错误: [具体错误信息]
}
}
最佳实践
- 重用客户端实例 - 避免频繁创建新的客户端
- 适当的速率限制 - 根据API使用情况调整速率限制
- 错误处理 - 始终检查和处理错误
- 超时设置 - 设置合理的HTTP超时时间
线程安全
API客户端是线程安全的,可以在多个goroutine中安全使用:
go
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
weakness, err := client.GetWeakness(fmt.Sprintf("%d", id))
if err != nil {
log.Printf("获取CWE-%d失败: %v", id, err)
return
}
fmt.Printf("CWE-%d: %s\n", id, weakness.Name)
}(i + 70) // 从CWE-70开始
}
wg.Wait()
// 输出: 并发获取多个CWE信息,每个都在单独的goroutine中执行