Hacker News 中文摘要

RSS订阅

每个GitHub对象都有两个ID -- Every GitHub object has two IDs

文章摘要

文章揭示了GitHub系统中每个对象都有两种ID:GraphQL API返回的全局节点ID和网页URL使用的数据库整数ID。作者在开发功能时发现两者不兼容,通过分析找到了两种ID之间的关联关系,避免了大规模数据迁移。

文章总结

标题:GitHub对象的双重ID系统解析

在开发Greptile(AI代码审查工具)的PR评论跳转功能时,我意外发现了GitHub API的ID机制秘密。这个看似简单的功能——通过存储的评论ID生成GitHub链接——却因两种ID系统的并存而陷入困境。

核心发现: 1. 双重ID体系 - GraphQL返回的节点ID(如PRRC_kwDOL4aMSs6Tkzl8)是全局唯一标识符 - REST API和网页URL使用纯数字数据库ID(如2475899260)

  1. 破解新格式ID 通过分析发现:
  • 节点ID采用Base64编码的MessagePack格式
  • 解码后数组结构为:[版本号, 仓库数据库ID, 对象数据库ID]
  • 数据库ID可通过提取数组末位元素或对解码值进行32位掩码获取
  1. 历史遗留问题 旧版仓库(如torvalds/linux)使用"010:Repository2325298"格式:
  • 包含类型枚举、对象类型名称和数据库ID
  • 新旧系统混杂:部分新对象仍使用旧格式,用户对象始终使用旧格式

技术实现方案: ```python import base64 import msgpack

def extractdatabaseid(nodeid): _, encoded = nodeid.split('_') return msgpack.unpackb(base64.b64decode(encoded))[-1] ```

这个发现不仅解决了URL生成问题,更揭示了GitHub为保持向后兼容所做的技术权衡。虽然官方文档建议将节点ID视为不透明字符串,但其内部结构实际上蕴含着重要的系统设计逻辑。这个案例生动展示了工程实践中"发现问题-分析模式-逆向工程"的完整解题路径。

评论总结

以下是评论内容的总结:

  1. 关于GitHub ID格式的讨论

    • 有评论指出GitHub的ID格式存在明确结构(如"010:Repository2325298"),并分析了其组成(类型枚举、前缀长度等)。
      引用:"010 is some type enum, followed by a colon, the word Repository, and then the database ID 2325298." (haileys)
      引用:"It's a classic length prefix. Repository has 10 chars, Tree has 4." (haileys)
    • 另一观点认为GraphQL的ID应被视为不透明字符串,其底层实现(如Base64编码)可能变化,不应依赖。
      引用:"GitHub's migration guide tells developers to treat the new IDs as opaque strings." (agwa)
  2. API设计争议

    • 部分开发者批评用户违反文档约定解析ID结构,导致API设计者需将用户视为"对手"。
      引用:"I have to treat my API's consumers as adversaries who will knowingly ignore guidance." (agwa)
    • 反对者认为应通过官方字段(如databaseId)或缓存机制获取数据,而非硬编码解析。
      引用:"You shouldn't rely on any of this implementation... query the 'databaseId' field directly." (innoying)
  3. 技术实现细节

    • 新ID格式被解析为"类型前缀msgpack负载"(如用户ID"UkgDOAAhEkg"对应[0, 541842])。
      引用:"Users are 'U_' and the data decodes to: [0, 541842]." (innoying)
    • 建议遵循GraphQL规范,使用全局节点ID而非自行构造。
      引用:"Global node IDs are supposed to be opaque in GraphQL." (siralonso)
  4. 实践建议

    • 推荐使用REST API与GraphQL的官方互操作字段(如node_iddatabaseId)。
    • 强调硬依赖ID结构会导致脆弱性,如格式变更时的重构问题。
      引用:"You find yourself playing a refactor cat-and-mouse game." (csomar)

总结:评论围绕是否应解析GitHub ID结构展开争论,一方从技术角度分析其可解码性,另一方强调遵循API设计原则避免依赖实现细节。多数观点倾向于通过官方字段获取数据以确保稳定性。