- 后端
- API设计
【免费下载链接】SpaceX-API
:rocket: Open Source REST API for SpaceX launch, rocket, core, capsule, starlink, launchpad, and landing pad data.
本篇技术指南以 SpaceX-API 仓库中的docs/history/v4/query.md为核心,系统讲解如何通过POST https://api.spacexdata.com/v4/history/query端点查询 SpaceX 历史事件数据。你将掌握该端点的请求格式、分页参数、全文检索与日期范围筛选等实战技巧,并深入理解其背后的 Mongoose 数据模型与 Koa 路由实现,从而能够在自己的应用中构建准确、高效的历史事件数据查询方案。
一、端点概览
/v4/history/query是 SpaceX-API v4 中历史事件(History)模块的查询入口,与返回全部数据的GET /v4/history(见 all.md)和返回单条数据的GET /v4/history/:id(见 one.md)不同,它通过POST请求体传入 MongoDB 查询条件与分页选项,实现精确筛选、排序和分页读取。
| 属性 | 值 |
|---|---|
| Method | POST |
| URL | https://api.spacexdata.com/v4/history/query |
| Auth required | False |
| Content-Type | application/json |
请求体默认结构:
{ "query": {}, "options": {} }其中:
query接受任意合法的 MongoDBfind()查询语句,用于条件过滤;options接受 mongoose-paginate-v2 支持的分页与字段控制选项,用于排序、分页、字段裁剪等。
完整的分页与查询语法说明见仓库根目录的 queries.md 指南,本节所有示例均遵循该指南约定。
二、底层实现:从路由到数据模型
在深入请求参数之前,先看该端点在仓库中的真实实现,这有助于理解各个选项是如何生效的。路由定义位于 routes/history/v4/index.js,核心代码为:
router.post('/query', cache(300), async (ctx) => { const { query = {}, options = {} } = ctx.request.body; try { const result = await History.paginate(query, options); ctx.status = 200; ctx.body = result; } catch (error) { ctx.throw(400, error.message); } });从源码可以确认以下实现事实:
- 请求体被解构为
query和options两个对象,未提供时默认为空对象; - 查询经由
History.paginate(query, options)执行,该方法来自 mongoose-paginate-v2 插件; - 查询失败时抛出
400 Bad Request,响应体为 Mongoose 错误信息及修正建议(与原文档中 Error Responses 一节描述一致); - 该路由还挂载了
cache(300)中间件,即 300 秒 Redis 缓存(详见 middleware/cache.js)。
数据模型位于 models/history.js,其 Schema 定义了可查询的字段结构:
const historySchema = new mongoose.Schema({ title: { type: String, default: null }, event_date_utc: { type: String, default: null }, event_date_unix: { type: Number, default: null }, details: { type: String, default: null }, links: { article: { type: String, default: null } }, }, { autoCreate: true }); const index = { title: 'text', details: 'text', }; historySchema.index(index); historySchema.plugin(mongoosePaginate); historySchema.plugin(idPlugin); const History = mongoose.model('History', historySchema);关键点:
title与details被声明为text 索引,这正是$text全文检索能够工作的前提(见下文示例);- 模型通过
mongoosePaginate插件获得paginate()能力,通过idPlugin暴露id字段; - 该模型经由 models/index.js 统一导出,供路由层引用。
三、成功响应结构
当查询成功时,接口返回200 OK,响应体是标准的分页结构(每页默认limit为 10):
{ "docs": [ { "title": "SpaceX successfully launches humans to ISS", "event_date_utc": "2020-05-30T19:22:00Z", "event_date_unix": 1590866520, "details": "This mission was the first crewed flight to launch from the United States since the end of the Space Shuttle program in 2011. It carried NASA astronauts Doug Hurley and Bob Behnken to the ISS.", "links": { "article": "https://spaceflightnow.com/2020/05/30/nasa-astronauts-launch-from-us-soil-for-first-time-in-nine-years/" } } ... ], "totalDocs": 7, "offset": 0, "limit": 10, "totalPages": 1, "page": 1, "pagingCounter": 1, "hasPrevPage": false, "hasNextPage": false, "prevPage": null, "nextPage": null }各字段含义如下:
| 字段 | 含义 |
|---|---|
docs | 当前页命中的历史事件数组,元素结构与 schema.md 中定义的一致 |
totalDocs | 满足查询条件的文档总数 |
offset | 当前页跳过的文档数 |
limit | 每页返回的最大条数 |
totalPages | 总页数 |
page | 当前页码(从 1 开始) |
pagingCounter | 当前页第一条记录的全局序号 |
hasPrevPage/hasNextPage | 是否存在上一页 / 下一页 |
prevPage/nextPage | 上一页 / 下一页页码,不存在时为null |
四、options 常用参数详解
options支持 mongoose-paginate-v2 的全部选项,原文档 queries.md 中归纳了最常用的几个:
select{ Object | String }—— 指定要返回的字段,默认返回全部字段;sort{ Object | String }—— 排序方式,如{ "event_date_unix": "desc" };offset{ Number }—— 跳过的文档数量,与page二选一即可设定起始位置;page{ Number }—— 页码;limit{ Number }—— 每页条数;pagination{ Boolean }—— 设为false时返回全部匹配文档而不施加limit(默认true);populate{ Array | Object | String }—— 需要填充为完整文档的关联路径。
4.1 分页与排序
按事件时间倒序取第二页(每页 5 条):
{ "query": {}, "options": { "page": 2, "limit": 5, "sort": { "event_date_unix": "desc" } } }4.2 字段裁剪
只返回标题与事件时间,减少响应体积:
{ "query": {}, "options": { "select": { "title": 1, "event_date_utc": 1 } } }4.3 关闭分页获取全量
{ "query": {}, "options": { "pagination": false } }五、query 过滤实战示例
query接受任意合法的 MongoDB 查询语法。以下示例均针对 History 集合的字段设计,可直接复制到请求体中验证。
5.1 按时间范围筛选
历史事件的event_date_utc为 ISO 8601 格式字符串,配合$gte、$lte可实现区间筛选。日期需符合 ISO 8601 才能正确比较:
{ "query": { "event_date_utc": { "$gte": "2017-06-22T00:00:00.000Z", "$lte": "2017-06-25T00:00:00.000Z" } } }也可以直接基于 Unix 时间戳字段event_date_unix进行数值区间查询,同样使用$gte/$lte。
5.2 全文检索
对title和details做关键词搜索。由于这两个字段已建立 text 索引,可直接使用$text:
{ "query": { "$text": { "$search": "ISS" } } }说明:$text会检索集合中的所有 text 索引字段。MongoDB 还支持$text的其他操作符(如$language、$caseSensitive、$diacriticSensitive),如需更多细节可查阅 MongoDB 官方$text参考文档。
5.3 组合条件
将范围筛选与精确匹配结合,例如查询 2020 年之后、且标题包含 "launch" 的事件:
{ "query": { "event_date_unix": { "$gte": 1577836800 }, "$text": { "$search": "launch" } }, "options": { "sort": { "event_date_unix": "asc" }, "limit": 20 } }六、错误响应
当查询条件非法(例如字段名拼写错误、操作符使用不当)时,接口返回:
Code:400 Bad Request
Content: Mongoose 错误信息,其中包含修正查询的建议。
这一行为与路由实现中ctx.throw(400, error.message)的处理逻辑一致:Mongoose 在解析查询失败时会抛出带描述信息的异常,异常信息会直接作为响应体返回,便于开发者定位问题。
七、与其他 History 端点的配合使用
/v4/history/query并非孤立的端点,它可与同模块的其他端点组合成完整的数据消费方案:
| 端点 | 用途 |
|---|---|
GET /v4/history | 获取全部历史事件(无分页,见 all.md) |
GET /v4/history/:id | 按 ID 获取单条历史事件(见 one.md) |
POST /v4/history/query | 按条件筛选 + 分页查询(本文主题) |
典型场景是:先用 query 端点按关键词或时间范围筛选出符合条件的id列表,再对关键事件调用单条端点获取完整详情;或者直接利用select裁剪字段,在一次请求中完成数据抽取。
八、补充说明
- 缓存行为:query 端点带有 300 秒 TTL 的 Redis 缓存(实现见 middleware/cache.js),且仅在
NODE_ENV=production且 Redis 可用时生效;可通过响应头spacex-api-cache(HIT/MISS)和Cache-Control: max-age=300判断缓存命中情况。 - 无需鉴权:该端点
Auth required: False,与创建(POST /v4/history,需要history:create权限)、更新(PATCH /v4/history/:id)、删除(DELETE /v4/history/:id)等写操作不同,查询数据是公开能力。 - 版本兼容:路由前缀为
/(v4|latest)/history(见 routes/history/v4/index.js),即v4与latest指向同一套实现,文档中的请求同样适用于latest版本。
九、小结
POST /v4/history/query是访问 SpaceX 历史事件数据的核心查询接口。通过组合 MongoDB 查询语法($text、$gte/$lte、$or等)与 mongoose-paginate-v2 分页选项(sort、limit、page、select、pagination),你可以精确检索特定时间段或主题的历史事件,并灵活控制返回结构与数据量。结合 models/history.js 中的 text 索引与 routes/history/v4/index.js 的实现细节,即可完整理解并可靠使用该端点。
- 后端
- API设计
【免费下载链接】SpaceX-API
:rocket: Open Source REST API for SpaceX launch, rocket, core, capsule, starlink, launchpad, and landing pad data.
相关推荐
如何把 Qwen Code 打成白标桌面版:Tauri 品牌化构建实战指南
如何把 Qwen Code 打成白标桌面版:Tauri 品牌化构建实战指南 需求摆在台面上:给 Qwen Code 做一个 "Acme AI" 的白标(whit
人工智能AI Agent代码智能体工具调用交互助手CLIQwenSpaceX-API Launchpad 查询接口实战指南:基于 POST /v4/launchpads/query 构建灵活查询与分页
SpaceX API Launchpad 查询接口实战指南:基于 POST /v4/launchpads/query 构建灵活查询与分页 本指南围绕 Space
后端API设计SpaceX-API 历史事件接口全解析:从 `GET /v4/history` 到查询、分页与源码实现
SpaceX API 历史事件接口全解析:从 GET /v4/history 到查询、分页与源码实现 本文以 docs/history/v4/all.md 定义
后端API设计
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考