Skip to content

API 客户端

text
# Related Code
- Sources/GitHubNotifierCore/Services/GitHubAPI.swift
- Sources/GitHubNotifierCore/Services/GitHubGraphQLClient.swift

概述

GitHubNotifier 使用双客户端架构与 GitHub API 交互:

客户端协议用途原因
GitHubAPIREST通知 CRUDGitHub GraphQL API 不支持通知端点
GitHubGraphQLClientGraphQLPR/Issue 详情、搜索单次请求获取多资源,减少网络开销

GitHubAPI (REST)

核心方法

swift
// Sources/GitHubNotifierCore/Services/GitHubAPI.swift:14-122

class GitHubAPI {
    // 获取所有未读通知
    func fetchNotifications() async throws -> [GitHubNotification]

    // 标记单条通知已读
    func markNotificationAsRead(threadId: String) async throws

    // 标记所有通知已读
    func markAllNotificationsAsRead() async throws
}

错误处理

swift
enum APIError: Error {
    case invalidURL
    case invalidResponse
    case httpError(Int)
    case decodingError(Error)
}

GitHubGraphQLClient

查询类型

查询用途响应模型
viewer获取当前用户信息Viewer
repository.pullRequest获取 PR 详情NotificationDetails
repository.issue获取 Issue 详情NotificationDetails
search跨仓库搜索SearchNode

批量查询优化

GraphQL 批量查询示例:

graphql
query {
  repo0: repository(owner: "owner1", name: "repo1") {
    pullRequest(number: 123) { ...prFields }
  }
  repo1: repository(owner: "owner2", name: "repo2") {
    issue(number: 456) { ...issueFields }
  }
}

响应模型层次

认证

两个客户端共享相同的认证机制:

swift
// Token 从 Keychain 获取
let token = KeychainHelper.getToken()

// REST: Authorization header
request.setValue("token \(token)", forHTTPHeaderField: "Authorization")

// GraphQL: Bearer token
request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")

Rate Limiting

API限制策略
REST5000/hour轮询间隔 30s,实际消耗约 120/hour
GraphQL5000 points/hour批量查询减少积分消耗

建议: 启用状态缓存 (prStateCache, issueStateCache) 避免重复查询。