- 后端
- API设计
【免费下载链接】SpaceX-API
:rocket: Open Source REST API for SpaceX launch, rocket, core, capsule, starlink, launchpad, and landing pad data.
导读
本文以docs/crew/v4/schema.md中定义的 Crew 数据模型为核心,系统讲解 SpaceX-API 开源仓库中宇航员(Dragon Crew)数据集合的字段结构、类型约束与取值枚举,并结合 models/crew.js 的 Mongoose 实现与 routes/crew/v4/index.js 的路由代码,说明该 Schema 如何被GET /v4/crew、GET /v4/crew/:id、POST /v4/crew/query等接口实际使用。读完本文,你将能准确理解每个字段的含义与校验规则,掌握基于该 Schema 编写查询、排序与populate关联展开的完整方法,并了解写操作(创建/更新/删除)在 Schema 层面的行为。
Crew Schema 总览
docs/crew/v4/schema.md给出了 Crew 集合的完整 JSON 结构定义,字段包括:name、status、agency、image、wikipedia与launches。其中status为唯一必填字段,且取值被限定为枚举["active", "inactive", "retired", "unknown"];launches是一个引用 Launch 集合的 UUID(ObjectId)数组。完整定义如下:
{ "name": { "type": "String", "default": null }, "status": { "type": "String", "required": true, "enum": ["active", "inactive", "retired", "unknown"] }, "agency": { "type": "String", "default": null }, "image": { "type": "String", "default": null }, "wikipedia": { "type": "String", "default": null }, "launches": [{ "type": "UUID" }] }字段逐个拆解:类型、默认值与校验规则
name(姓名)
- 类型:
String - 默认值:
null - 语义:宇航员的全名,例如示例数据中的
"Robert Behnken"、"Douglas Hurley"。
该字段在 models/crew.js 中实现为type: String, default: null,表示该字段在文档创建时如未提供则保存为null,允许为空。
status(状态,唯一必填字段)
- 类型:
String - 必填:
required: true - 枚举:
["active", "inactive", "retired", "unknown"]
status是 Crew 文档中唯一强制要求存在的字段,对应源码 models/crew.js。其取值含义:
| 取值 | 含义 | 示例场景 |
|---|---|---|
active | 现役 | 处于任务名单中的现役宇航员,如 Robert Behnken |
inactive | 非现役(在编但未执行任务) | 已入选但尚未执行龙飞船任务的宇航员 |
retired | 已退役 | 已从宇航员岗位退休 |
unknown | 状态未知 | 无法确认当前状态 |
注意:枚举校验由 Mongoose 在文档保存与更新校验阶段强制执行,而非仅靠 API 层判断。这意味着通过POST /v4/crew创建或PATCH /v4/crew/:id更新时,若传入枚举之外的值(如"suspended"),Mongoose 会抛校验错误并返回400。
agency(所属机构)
- 类型:
String - 默认值:
null - 语义:宇航员所属的航天机构或任务运营商,例如
"NASA"。
与name一样,未提供时保存为null,见 models/crew.js。
image(头像图片)
- 类型:
String - 默认值:
null - 语义:宇航员头像图片的 URL,例如
"https://imgur.com/0smMgMH.png"。
该字段存储的是完整的图片外链地址(示例中为 Imgur 图床),API 本身不托管图片文件。
wikipedia(维基百科链接)
- 类型:
String - 默认值:
null - 语义:宇航员在维基百科上的条目链接,例如
"https://en.wikipedia.org/wiki/Robert_L._Behnken",供查阅其详细履历。
launches(参与任务)
- 类型:
UUID数组 - 默认值:数组为空
- 语义:该宇航员参与的发射任务 ID 列表。
在 Schema 文档中其类型标注为UUID,对应源码 models/crew.js 的实现:
launches: [{ type: mongoose.ObjectId, ref: 'Launch', }],即底层实际是mongoose.ObjectId数组,并通过ref: 'Launch'声明了与 Launch 集合(models/launches.js)的外键关系。这正是后续populate查询能够将 ID 展开为完整发射文档的关键。
补充:文档级扩展(id字段与时间戳)
Schema 文档中没有列出的id字段,在 API 响应中始终存在(如"5ebf1a6e23a9a60006e03a7a")。它由 models/crew.js 中的插件提供:
crewSchema.plugin(mongoosePaginate); crewSchema.plugin(idPlugin);idPlugin(mongoose-id)为文档生成对外暴露的id字段;mongoosePaginate为集合启用paginate()分页能力,支撑/query接口;- 此外 models/crew.js 为
name字段建立了text文本索引,使/query接口支持 MongoDB 的全文搜索($text查询)。
从 Schema 到接口:Crew 路由如何消费该模型
Crew 数据模型被挂载在/(v4|latest)/crew前缀下,路由实现见 routes/crew/v4/index.js。共有五个接口消费该 Schema:
查询类接口(公开,无鉴权)
| 方法 | 路径 | 对应 Schema 用法 | 文档 |
|---|---|---|---|
GET | /v4/crew | Crew.find({})返回全部文档 | docs/crew/v4/all.md |
GET | /v4/crew/:id | Crew.findById(id)返回单条,不存在时404 | docs/crew/v4/one.md |
POST | /v4/crew/query | Crew.paginate(query, options)分页查询 | docs/crew/v4/query.md |
以查询单个成员为例,响应体中会包含 Schema 中全部六个业务字段加上id:
{ "name": "Douglas Hurley", "agency": "NASA", "image": "https://i.imgur.com/ooaayWf.png", "wikipedia": "https://en.wikipedia.org/wiki/Douglas_G._Hurley", "launches": [ "5eb87d46ffd86e000604b388" ], "status": "active", "id": "5ebf1b7323a9a60006e03a7b" }写操作类接口(需鉴权)
| 方法 | 路径 | Schema 行为 |
|---|---|---|
POST | /v4/crew | new Crew(body)创建,校验失败返回400,成功返回201 |
PATCH | /v4/crew/:id | Crew.findByIdAndUpdate(id, body, { runValidators: true })更新 |
DELETE | /v4/crew/:id | Crew.findByIdAndDelete(id)删除 |
注意两点与 Schema 强相关的行为:
PATCH接口显式开启了runValidators: true,因此更新操作同样会触发status枚举与必填校验,而非只校验创建;- 写操作全部通过
auth与authz('crew:create')等中间件保护(见 middleware/auth.js),需要携带spacex-key请求头,缺少有效密钥时返回401。根据 docs/README.md 的说明,所有create/update/delete路由均为"破坏性"路由,必须鉴权。
缓存与性能:Crew 响应的 TTL 策略
所有查询类路由都包裹了cache(300)中间件(见 routes/crew/v4/index.js),即300 秒(5 分钟)的 Redis 响应缓存。这与 docs/README.md 中"crew — 5 minutes"的缓存说明一致。
其底层实现见 middleware/cache.js:
- 仅在生产环境(
NODE_ENV=production)且 Redis 可用时启用; - 缓存键由
blake3对METHOD + URL + request body哈希生成,因此POST /v4/crew/query的查询体也会参与缓存键计算,不同查询体互不污染; - 命中时响应头会带
spacex-api-cache: HIT,未命中回源后写入为MISS,便于排查; - 同时设置
Cache-Control: max-age=300供 CDN 与客户端使用。
这意味着同一时刻大量针对 Crew 数据的读取请求会命中缓存,有效降低 MongoDB 压力。
查询实战:基于 Schema 字段的组合查询与关联展开
POST /v4/crew/query的请求体固定为{"query": {}, "options": {}},完整用法见 docs/queries.md。
按状态过滤
筛选所有现役宇航员:
{ "query": { "status": "active" }, "options": { "limit": 10 } }组合条件:状态 + 机构
同时命中status与agency两个字段:
{ "query": { "status": "active", "agency": "NASA" }, "options": { "sort": { "name": "asc" } } }全文搜索
由于name字段建立了文本索引(models/crew.js),可直接使用 MongoDB 的$text操作符搜索姓名:
{ "query": { "$text": { "$search": "Hurley" } } }populate:把任务 ID 展开为完整发射文档
launches字段存储的是引用Launch集合的 ObjectId,默认响应中仅返回 ID。通过options.populate可以将其展开为完整的发射对象:
{ "query": {}, "options": { "populate": ["launches"] } }响应中launches数组的每一项将由 ID 替换为对应发射文档(含name、date_utc、rocket等完整字段)。也可以只挑选所需子字段:
{ "query": {}, "options": { "populate": [ { "path": "launches", "select": { "name": 1, "date_utc": 1 } } ] } }populate还支持嵌套展开(例如在launches内继续展开其引用的rocket),原理与 docs/queries.md 中 payloads 的示例一致,其数据来源正是ref: 'Launch'这一 Schema 关联声明。
分页返回结构
无论是否使用populate,/query接口都会返回统一的分页结构(totalDocs、limit、totalPages、page、hasPrevPage等),例如:
{ "docs": [ ... ], "totalDocs": 2, "offset": 0, "limit": 10, "totalPages": 1, "page": 1, "pagingCounter": 1, "hasPrevPage": false, "hasNextPage": false, "prevPage": null, "nextPage": null }分页由mongoosePaginate插件支撑,options中可通过page/offset控制跳过位置,pagination: false可关闭分页返回全量。
从源码看 Schema 的完整闭环
将本文内容串起来,Crew 数据模型在仓库中的完整实现链路是:
- 定义:Schema 结构在 models/crew.js 中定义(业务文档 docs/crew/v4/schema.md 是其可读版本),并通过 models/index.js 统一导出为
Crew; - 注册:路由在 routes/crew/index.js 中按 v4 版本动态加载 routes/crew/v4/index.js,挂载到
/v4/crew前缀; - 读写:五个路由分别调用
find/findById/paginate/save/findByIdAndUpdate/findByIdAndDelete,status的枚举校验在写路径上被强制执行; - 加速:读路径由
cache(300)中间件做 5 分钟 Redis 缓存; - 关联:
launches通过ref: 'Launch'与外键在查询时用populate展开。
对于需要二次开发或本地调试的读者,可直接基于该模型扩展字段(如添加birth_date),只需同步修改 models/crew.js 与 docs/crew/v4/schema.md 即可保持文档与实现一致;运行时传入非法status值时,接口会返回带 Mongoose 错误提示的400响应,可直接作为字段约束的验证手段。
- 后端
- API设计
【免费下载链接】SpaceX-API
:rocket: Open Source REST API for SpaceX launch, rocket, core, capsule, starlink, launchpad, and landing pad data.
相关推荐
SpaceX-API v4 Crew 接口详解:数据模型、查询分页与缓存实现
SpaceX API v4 Crew 接口详解:数据模型、查询分页与缓存实现 导读 本文以 SpaceX API 开源仓库的 Crew 接口文档 https:/
后端API设计SpaceX-API Capsule Schema 全解析:Dragon 胶囊数据模型的字段定义、约束与查询实践
SpaceX API Capsule Schema 全解析:Dragon 胶囊数据模型的字段定义、约束与查询实践 本文以 SpaceX API 仓库中 docs
后端API设计SpaceX-API Crew 数据查询实战指南:掌握 /v4/crew/query 端点与 MongoDB 分页检索
SpaceX API Crew 数据查询实战指南:掌握 /v4/crew/query 端点与 MongoDB 分页检索 导读 本文围绕 SpaceX API 开
后端API设计
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考