尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Puter Subdomain 对象完全解析:结构、字段语义与托管实现机制

Puter Subdomain 对象完全解析:结构、字段语义与托管实现机制 Puter Subdomain 对象完全解析结构、字段语义与托管实现机制【免费下载链接】puter The Internet Computer! Free, Open-Source, and Self-Hostable.项目地址: https://gitcode.com/GitHub_Trending/pu/puterSubdomain是 Puter 托管Hosting能力对外暴露的核心数据对象它把一个唯一子域名与其在用户文件系统中的站点根目录绑定在一起。本文围绕 src/docs/src/Objects/subdomain.md 中定义的三个标准字段展开并结合仓库中驱动层、存储层与上层托管 API 的实现证据说明该对象在每个字段背后的确切含义、类型约束与底层数据来源帮助你准确解析puter.hosting各接口的返回结果并为二次开发或排查站点问题建立字段级认知。Subdomain 对象概述Subdomain对象封装了一次托管站点的完整描述信息。它的产生场景非常明确当应用调用托管 API如puter.hosting.create把一个文件系统目录发布成可公开访问的站点后接口返回的就是这样一个对象此后调用puter.hosting.get或puter.hosting.list拿到的同样是它或它的数组。从文档定义来看该对象包含三个标准属性属性类型含义uidString该子域名的全局唯一标识符subdomainString子域名名称即主域名之前的那一部分root_dirFSItem代表该子域名根目录的 FSItem 对象即站点文件实际存放的目录也就是说Subdomain回答的是三个问题这是哪一个站点uid、它的对外地址是什么subdomain、它从哪个目录取内容root_dir。字段详解uidString一个字符串包含该子域名的唯一标识符。它由后端在写入数据库记录时通过 UUID v4 生成是每条子域名记录的身份键。在整个托管生命周期中删除、更新、读取都以它为准——例如 delete 接口 在成功删除后会返回形如{ success: true, uid: subdomain-uid }的对象这里回传的就是同一个uid。subdomainString一个字符串包含子域名的名称也就是主域名之前的那一部分。文档给出了典型例子在example.puter.site中example就是子域名。因此完整访问地址可拼为https://${site.subdomain}.puter.site这与 create 接口文档示例 中的用法一致。需要注意subdomain在系统层面是**不可变immutable**字段。在存储层subdomain被明确列入只读列集合因为它同时承载 DNS 与 ACL 等外部绑定改名会导致旧名字上的接线全部失效详见 SubdomainStore.ts 的READ_ONLY_COLUMNS定义。所以通过puter.hosting.update只能更换站点指向的目录而无法更换子域名本身。root_dirFSItem一个 FSItem 对象表示该子域名的根目录即站点文件被存储的目录。FSItem 本身在 Puter 文档中被定义为代表文件系统中的一个文件或目录的对象它包含id、name、path、isDir、created、modified等常规字段详见 FSItem 对象。在托管语义中root_dir的定位是作为公开站点内容源的目录托管服务会把该目录下的内容作为站点对外提供。理解这一点有助于你区分Subdomain对象与普通文件对象——前者把网络命名空间子域名与文件系统命名空间目录显式地绑定在了一起。更深一层的运行时形态从源码看完整响应结构上表是文档定义的标准三字段。若对照当前仓库的实际实现客户端在真实响应中还可能观察到更多字段——它们是对同一对象更完整的序列化结果。后端驱动在 SubdomainDriver.ts 的#shapeRow方法中按如下结构组装响应{ uid, // row.uuid subdomain, // 子域名名称 domain, // 自定义域名未设置时为空字符串 root_dir, // 站点根目录FSItem 形态见下 associated_app, // 派生出的关联应用无则 null created_at, // ISO 8601 时间字符串 owner, // { username, uuid } app_owner, // 创建该记录的应用完整应用形态无则 null protected // boolean受保护站点标记 }其中值得关注的三点均能帮助更准确地消费这个对象root_dir的实际载荷驱动通过mapEntryToSubdomainRootDirSubdomainDriver.ts将 FS 记录重塑为内嵌对象字段包含id/uid、name、path、dirname、is_dir、size、modified、created等 FSItem 常见信息同时附加与托管相关的语义标记writable站点属主对其根目录恒为可写因此固定为true、subdomains、workers、has_website。也就是说拿到root_dir后可以直接读取path/name定位站点内容目录而无需再发起一次 FS 查询。关联应用是读时派生而非写入时声明associated_app不是创建时由客户端写入的而是驱动根据同一属主 index_url命中该子域名主机候选的规则实时推导见#deriveAssociatedAppIdByRowUuidSubdomainDriver.ts。因此在解析返回对象时不应假设创建时传入过任何 app 关联参数。Worker 部署行不会出现在面向站点的结果中Worker 部署记录同样存放于subdomains表中但使用workers.puter.前缀常量WORKER_SUBDOMAIN_PREFIX见 SubdomainStore.ts。站点的读、列表接口都会将该前缀的行过滤掉与 list 接口文档 中Worker-backed subdomains 永远不会出现在结果里的说明完全对应。与 FSItem 的关系为什么用目录而非静态文件来定义站点root_dir的类型声明为 FSItem这背后是 Puter 托管模型的一个关键设计一个子域名对应一个可变的目录而非一组一次性上传的静态文件。这样带来的实际效果是站点可以随目录内容更新修改root_dir指向的目录中的文件站点内容随之变化无需重建子域名指向关系可迁移puter.hosting.update(subdomain, dirPath)允许把子域名重新指向另一个目录返回的Subdomain对象中root_dir会反映新的绑定详见 update 接口文档删除站点不影响文件按 delete 接口文档 的定义删除子域名只是把目录与子域名断开连接目录本身不会被删除——这正是root_dir作为独立 FSItem 被引用、而不是被嵌套复制所保证的边界。因此在实践中可以这样理解二者FSItem描述数据放在哪Subdomain描述数据如何被公开访问root_dir正是两者交汇的枢纽字段。典型使用流程从创建到读取一个 Subdomain要拿到一个完整的Subdomain对象最直接的方式是通过puter.hosting系列接口。以下流程整合自仓库托管相关文档的示例用法。1. 创建站点create 接口文档// 以某个随机名字在 puter.site 下创建站点 let subdomain puter.randName(); const site await puter.hosting.create(subdomain, dirName); // site 即为 Subdomain 对象可以直接拼接访问地址 puter.print(Website hosted at: https://${site.subdomain}.puter.site);创建时只需提供子域名名称与一个目录路径后端会自动完成名称校验 → 唯一性检查 → 配额检查 → 目录存在性检查 → 发布权限检查 → 写入记录。创建成功与否、返回对象与否都取决于这些前置校验能否全部通过。2. 读取站点信息get 接口文档const site2 await puter.hosting.get(site.subdomain); // 文档示例中即可通过 site2.subdomain / site2.uid 直接访问字段 puter.print(Website retrieved: subdomain${site2.subdomain}.puter.site UID${site2.uid});3. 更新站点指向目录update 接口文档await puter.hosting.update(subdomain, newDirPath); // 更换 root_dir 绑定4. 列出与删除list 接口文档、delete 接口文档const { items } await puter.hosting.list(); // items 为 Subdomain 数组 await puter.hosting.delete(site.subdomain); // 成功后返回 { success: true, uid }list 接口支持limit/offset/cursor分页需要了解这些分页参数的约定可参考仓库中的 pagination 说明。结合 pagination 文档 中关于游标语义的说明可以准确遍历大批量子域名列表。从后端实现看字段的可靠性边界作为开发者你需要知道Subdomain各字段在服务端受到怎样的约束以便正确判断返回值的形态与出错场景。名称约束决定subdomain字段的取值范围。驱动层在#validateSubdomain中强制执行如下规则SubdomainDriver.ts长度上限 64 字符常量SUBDOMAIN_MAX_LEN仅允许小写字母、数字与连字符且不能以连字符开头或结尾正则^a-z0-9?$输入会先被trim().toLowerCase()归一化命中保留字列表www、api、mail、ftp、admin、localhost、ns1、ns2、smtp、pop、imap、blog、dev、staging、test会直接拒绝。因此你在消费返回对象时可以放心假设subdomain字段是一个规范化之后的小写合法名称。唯一性约束保证同一subdomain值全局唯一。创建时先做存在性检查再依赖数据库唯一索引兜底两个并发请求同时抢注同一名字时后到者会收到与常规冲突一致的错误而非 500SubdomainDriver.ts。这意味着subdomain字段天然可作为站点的稳定业务键使用。配额与频率约束影响你能拥有多少个对象。每个用户可创建的子域名数量受限默认上限为 500可通过配置max_subdomains_per_user调整SubdomainDriver.ts同时驱动声明了默认 200 次/10 秒、创建操作 120 次/60 秒的速率限制以及默认 20 的并发上限免费/临时订阅账号另有更紧的额度SubdomainDriver.ts。当响应报出subdomain_limit_reached或conflict类错误时即可据此定位原因。缓存语义提示字段读取时机。存储层对subdomain → 记录的解析做了 Redis 缓存正向结果 TTL 为 1 小时未命中时写入 10 秒的负缓存标记写后立即读取需使用主库读取以保证一致性SubdomainStore.ts。这解释了为什么刚执行过创建/更新操作后短时间内对同一名字的查询必须能够读到最新root_dir——实现上对应primary 读路径可跳过可能滞留旧值的缓存。总结Subdomain对象是 Puter 托管体系的接线文档式数据结构uid提供稳定身份subdomain提供对外寻址名称root_dir通过 FSItem 指向内容源目录。解析它时只需先消费文档定义的三字段即可完成绝大多数业务逻辑若需更丰富的上下文自定义域名、关联应用、创建时间、属主信息、受保护标记则可结合本仓库 SubdomainDriver.ts 中的完整序列化结构按需读取。理解上述字段的约束与派生规则能让你在使用puter.hosting系列接口时更准确地判断返回值形态、预测错误场景并据此构建可靠的站点管理逻辑。【免费下载链接】puter The Internet Computer! Free, Open-Source, and Self-Hostable.项目地址: https://gitcode.com/GitHub_Trending/pu/puter创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表