- 后端
- API设计
【免费下载链接】SpaceX-API
:rocket: Open Source REST API for SpaceX launch, rocket, core, capsule, starlink, launchpad, and landing pad data.
本文以 SpaceX-API 开源仓库中 docs/roadster/v4/query.md 为核心骨架,深入讲解POST https://api.spacexdata.com/v4/roadster/query查询端点的完整用法。你将掌握该端点与其它/query端点的本质差异(不支持分页、仅暴露select)、query与options请求体的正确构造方式、返回的 26 个字段的物理与轨道语义,以及背后由 Koa 路由、Mongoose 模型与 Redis 缓存构成的实现原理。
一、端点速览:Roadster 查询接口的三大特性
Roadster 是 2018 年 2 月 Falcon Heavy 首飞时搭载的"星舰假载荷"——一辆由 Starman 假人驾驶的 Tesla Roadster 敞篷跑车,如今成为一颗绕太阳运行的人造小天体。SpaceX-API 将其轨道与距离数据整理为单个文档,并提供两个端点访问:GET /v4/roadster(直接获取全量数据)与本文主角POST /v4/roadster/query(按需筛选字段)。
查询端点关键参数如下:
| 项目 | 值 |
|---|---|
| Method | POST |
| URL | https://api.spacexdata.com/v4/roadster/query |
| Auth required | False(公开只读,无需 API Key) |
| 请求体 | query+options |
| 成功响应 | 200 OK |
| 失败响应 | 400 Bad Request(返回 Mongoose 错误提示) |
该端点有三个显著特征:
- 无需认证。与仓库中 routes/roadster/v4/index.js 的实现一致,公开 POST 即可查询。
- 仅返回单条文档。底层使用
Roadster.findOne(query)而非find(),因此不存在文档列表。 - 不支持分页,
options中只有select生效,用于控制返回字段的隐藏与显示。
对比:其它集合的
/query端点(如 docs/launches/v4/query.md)基于 mongoose-paginate 返回docs、totalDocs、page、limit等分页元数据;而 Roadster 查询返回的是单条 Roadster 对象,两者结构完全不同。通用的分页与聚合参数请参考 docs/queries.md。
二、请求体构造:query与options的用法
/v4/roadster/query接受与其它查询端点相同的请求体结构,但能力范围按文档明确说明做了裁剪。
2.1 官方文档给出的最小示例
原文档给出的可复制示例如下:
{ "query": {}, "options": { "select": { "norad_id": 1 } } }query:任何合法的 MongoDBfind()过滤条件(见 docs/queries.md),用于筛选 Roadster 文档字段。options.select:值为1表示包含该字段,值为0表示排除该字段。上述示例表示只返回norad_id字段。
2.2 源码实现:options中只有select被使用
查看仓库路由源码 routes/roadster/v4/index.js:
router.post('/query', cache(300), async (ctx) => { const { query = {}, options = { select: '' } } = ctx.request.body; try { const result = await Roadster.findOne(query).select(options.select).exec(); ctx.status = 200; ctx.body = result; } catch (error) { ctx.throw(400, error.message); } });从源码可以看出三点关键事实:
query与options均有默认值(空对象与{ select: '' }),即请求体完全为空时也会返回全部字段的 Roadster 数据。options中只解构并使用了select,sort、limit、page、populate等其它选项在此端点中被忽略(文档中的 NOTE 与源码互相印证)。- 返回体是
Roadster.findOne(query).select(...)的结果,即单个对象,而非数组。
2.3select的两种写法
select支持对象与字符串两种形式(MongooseQuery#select的标准用法):
{ "query": {}, "options": { "select": { "name": 1, "details": 1, "id": 1 } } }{ "query": {}, "options": { "select": "name details id" } }包含/排除混用时需注意 Mongoose 约束:除_id外,不能将包含字段(1)与排除字段(0)混用于同一查询。roadster 模型通过idPlugin(见 models/roadster.js)在返回时自动附带id字段。
三、成功响应:完整示例与字段语义详解
原文档给出的200 OK完整响应内容如下(26 个字段):
{ "flickr_images": [ "https://farm5.staticflickr.com/4615/40143096241_11128929df_b.jpg", "https://farm5.staticflickr.com/4702/40110298232_91b32d0cc0_b.jpg", "https://farm5.staticflickr.com/4676/40110297852_5e794b3258_b.jpg", "https://farm5.staticflickr.com/4745/40110304192_6e3e9a7a1b_b.jpg" ], "name": "Elon Musk's Tesla Roadster", "launch_date_utc": "2018-02-06T20:45:00.000Z", "launch_date_unix": 1517949900, "launch_mass_kg": 1350, "launch_mass_lbs": 2976, "norad_id": 43205, "epoch_jd": 2459014.345891204, "orbit_type": "heliocentric", "apoapsis_au": 1.663950009802517, "periapsis_au": 0.9859657216725529, "semi_major_axis_au": 196.2991348009594, "eccentricity": 0.2558512635239784, "inclination": 1.077499248052439, "longitude": 317.0839961949045, "periapsis_arg": 177.5240278992875, "period_days": 557.059427465354, "speed_kph": 72209.97792, "speed_mph": 44869.18619012833, "earth_distance_km": 220606726.83228922, "earth_distance_mi": 137078622.45850638, "mars_distance_km": 89348334.47067611, "mars_distance_mi": 55518463.93837848, "wikipedia": "https://en.wikipedia.org/wiki/Elon_Musk%27s_Tesla_Roadster", "video": "https://youtu.be/wbSwFU6tY1c", "details": "Elon Musk's Tesla Roadster is an electric sports car that served as the dummy payload for the February 2018 Falcon Heavy test flight and is now an artificial satellite of the Sun. Starman, a mannequin dressed in a spacesuit, occupies the driver's seat. The car and rocket are products of Tesla and SpaceX. This 2008-model Roadster was previously used by Musk for commuting, and is the only consumer car sent into space.", "id": "5eb75f0842fea42237d7f3f4" }这些字段的类型与语义与 models/roadster.js 中定义的 Mongoose Schema、以及 docs/roadster/v4/schema.md 一一对应,可分为五组理解:
3.1 身份与任务信息(String 类型)
| 字段 | 含义 |
|---|---|
name | 对象名称:"Elon Musk's Tesla Roadster" |
launch_date_utc | 发射时间(UTC 字符串) |
launch_date_unix | 发射时间(Unix 时间戳,秒) |
launch_mass_kg | 发射质量(千克,1350 kg) |
launch_mass_lbs | 发射质量(磅,2976 lbs) |
details | 背景说明:作为 2018 年 2 月 Falcon Heavy 试飞任务的假载荷升空,现为绕太阳运行的人造卫星 |
wikipedia/video | 百科词条与发射视频链接 |
flickr_images | 图片 URL 数组(String 数组类型) |
3.2 轨道根数(Number 类型,源于 JPL Horizons)
| 字段 | 含义 |
|---|---|
norad_id | NORAD 编号(43205),用于空间目标识别 |
epoch_jd | 轨道历元(儒略日) |
orbit_type | 轨道类型:heliocentric(日心轨道) |
apoapsis_au | 远日点距离(天文单位 AU) |
periapsis_au | 近日点距离(AU) |
semi_major_axis_au | 半长轴(AU) |
eccentricity | 轨道偏心率(0 为圆,1 为抛物线) |
inclination | 轨道倾角(度) |
longitude | 升交点黄经(度) |
periapsis_arg | 近地点幅角(度) |
period_days | 轨道周期(天,约 557 天) |
3.3 运动速度(Number 类型)
| 字段 | 含义 |
|---|---|
speed_kph | 轨道速率(千米/小时) |
speed_mph | 轨道速率(英里/小时) |
3.4 距离量(Number 类型)
| 字段 | 含义 |
|---|---|
earth_distance_km/earth_distance_mi | Roadster 与地球的距离(公里/英里) |
mars_distance_km/mars_distance_mi | Roadster 与火星的距离(公里/英里) |
3.5 文档标识
| 字段 | 含义 |
|---|---|
id | 文档唯一 ID(MongoDB ObjectId 字符串,由idPlugin自动生成) |
速度与距离数据为动态数据:它们由定时任务定期从 NASA JPL Horizons 系统抓取更新(详见下文),不同时间查询会得到不同的数值,这是该端点数据会"随时间漂移"的原因。
四、错误响应与排查建议
原文档指出非200情况下的错误响应:
| 状态码 | 含义 |
|---|---|
400 Bad Request | Mongoose 错误,响应体附带修正查询的建议 |
典型触发场景:
query中使用了字段不存在或类型不匹配的条件(如对Number类型的norad_id传入字符串正则)。select中混用包含与排除字段(除_id外)。- 请求体不是合法 JSON。
对照源码 routes/roadster/v4/index.js,Roadster.findOne(query).select(...)抛出的任何异常都会被捕获并转换为ctx.throw(400, error.message),将底层 Mongoose 的错误信息原样返回,便于开发者定位问题。
五、源码级原理:这条路是怎么搭起来的
5.1 路由与模型
Roadster 端点位于 routes/roadster/v4/index.js,路由前缀为/(v4|latest)/roadster,这意味着v4与latest两个版本别名共享同一套处理逻辑:
GET /→Roadster.findOne({}),返回全部字段;POST /query→Roadster.findOne(query).select(options.select);PATCH /:id→ 需要auth+authz('roadster:update')权限,供内部定时任务更新数据,普通用户不可用。
模型定义在 models/roadster.js,所有字段均映射为 Mongoose Schema,并通过idPlugin暴露id字段。数据实体结构另见 docs/roadster/v4/schema.md。
5.2 动态数据从哪来:JPL Horizons 定时同步
查询接口返回的轨道、速度、距离数据并非人工维护的静态值,而是由 jobs/roadster.js 中的定时任务维护的:
- 任务向 NASA JPL Horizons API 发起三次并行请求,分别获取轨道根数(
COMMAND='-143205'即 Roadster 的天体编号,日心参考系)、地球距离、火星距离; - 使用一系列正则表达式从返回文本中解析出
epoch_jd、apoapsis_au、eccentricity、period_days、speed_kph、earth_distance_km、mars_distance_km等字段; - 最后通过
PATCH /roadster/{id}(携带spacex-key头)回写数据库。
这也是为什么响应中orbit_type为heliocentric、而apoapsis_au/periapsis_au等轨道量以天文单位计数的原因——它们直接源自 JPL 的日心轨道根数输出。数据同步流程的编排与启动方式可参考 jobs/worker.js 等任务基础设施。
5.3 缓存行为:300 秒 TTL
/query与GET /都包裹了cache(300)中间件(见 middleware/cache.js)。其行为要点:
- 仅在生产环境(
NODE_ENV=production)且 Redis 可用时启用缓存; - 缓存键由
METHOD + URL + JSON.stringify(request.body)经 BLAKE3 哈希生成,因此不同查询体不会互相污染缓存; - 命中时响应头出现
spacex-api-cache: HIT,未命中写入后标记MISS,并设置Cache-Control: max-age=300; - 这意味着同一查询在 300 秒内重复请求会直接命中缓存,速度更快,但动态字段(如距离)的更新会有最多 5 分钟的延迟可见。
六、实战示例:三种典型用法
6.1 返回全部字段
curl -X POST https://api.spacexdata.com/v4/roadster/query \ -H "Content-Type: application/json" \ -d '{}'6.2 只关注轨道根数(select 包含模式)
curl -X POST https://api.spacexdata.com/v4/roadster/query \ -H "Content-Type: application/json" \ -d '{"query": {}, "options": {"select": {"name": 1, "orbit_type": 1, "semi_major_axis_au": 1, "eccentricity": 1, "period_days": 1}}}'6.3 排除大字段(select 排除模式)
curl -X POST https://api.spacexdata.com/v4/roadster/query \ -H "Content-Type: application/json" \ -d '{"query": {}, "options": {"select": {"flickr_images": 0, "details": 0}}}'6.4 用query条件过滤(配合 select)
虽然集合中通常只有一条文档,但query依然生效,可按字段值精确过滤:
curl -X POST https://api.spacexdata.com/v4/roadster/query \ -H "Content-Type: application/json" \ -d '{"query": {"norad_id": 43205}, "options": {"select": {"name": 1, "norad_id": 1}}}'七、与相关文档的衔接
- 若只需获取完整 Roadster 数据、无需筛选字段,可使用
GET https://api.spacexdata.com/v4/roadster,文档见 docs/roadster/v4/get.md; - Roadster 全部字段的类型定义见 docs/roadster/v4/schema.md;
- 其它集合
/query端点的分页、排序、populate 用法(本端点不支持)见 docs/queries.md; - 各业务集合的查询端点总览见 docs/README.md。
总结
POST /v4/roadster/query是访问 SpaceX-API 中 Roadster 轨道与距离数据的精简单点:它不支持分页与其它options,仅通过query过滤 +select裁剪字段;响应为单条文档,涵盖身份信息、JPL 日心轨道根数、实时速度与地/火距离等 26 个字段;底层由 Koa 路由(routes/roadster/v4/index.js)、Mongoose 模型(models/roadster.js)、JPL 定时同步任务(jobs/roadster.js)与 300 秒 Redis 缓存(middleware/cache.js)共同支撑。理解其请求契约与字段语义,即可在应用中准确消费这颗"星际跑车"的实时轨道数据。
- 后端
- API设计
【免费下载链接】SpaceX-API
:rocket: Open Source REST API for SpaceX launch, rocket, core, capsule, starlink, launchpad, and landing pad data.
相关推荐
SpaceX-API Starlink 卫星查询接口实战:v4/starlink/query 请求构建、分页机制与源码解析
SpaceX API Starlink 卫星查询接口实战:v4/starlink/query 请求构建、分页机制与源码解析 本篇指南围绕 SpaceX API
后端API设计SpaceX-API v4 单个着陆场查询接口实战:GET /v4/landpads/:id 返回结构、字段语义与源码实现解析
SpaceX API v4 单个着陆场查询接口实战:GET /v4/landpads/:id 返回结构、字段语义与源码实现解析 本文以 SpaceX API 开
后端API设计SpaceX-API v4 Capsules 全量查询接口详解:GET /v4/capsules 的字段语义、缓存机制与源码实现
SpaceX API v4 Capsules 全量查询接口详解:GET /v4/capsules 的字段语义、缓存机制与源码实现 本指南围绕 SpaceX AP
后端API设计
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考