ModReleaser/docs/modrinth/get.md
2026-07-06 04:56:50 +08:00

403 lines
13 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Modrinth 获取版本信息 API 使用文档
本文档描述如何通过 Modrinth API 获取项目的版本列表以及每个版本的详细信息,包括版本名(`name`)、版本号(`version_number`)、文件名(`filename`)、下载地址等。
---
## 基本信息
所有版本读取接口均为 **公开接口,无需认证**。但如果项目包含 `draft`(草稿)状态的版本,获取它们可能需要认证。
| 项目 | 内容 |
|------|------|
| **生产环境** | `https://api.modrinth.com/v2` |
| **测试环境** | `https://staging-api.modrinth.com/v2` |
| **认证** | 公开接口无需认证;获取草稿版本需要 PAT |
| **Rate Limit** | 每 IP 每分钟 300 请求 |
---
## 接口一:列出项目的所有版本
获取指定项目下的全部版本列表。这是获取版本信息最常用的入口。
| 项目 | 内容 |
|------|------|
| **端点** | `GET /project/{id\|slug}/version` |
| **认证** | 否(公开) |
| **成功响应码** | `200` |
| **响应体** | `Version[]` — Version 对象数组 |
### 路径参数
| 参数 | 说明 | 示例 |
|------|------|------|
| `id\|slug` | 项目的 8 位 base62 ID 或 slug别名 | `AABBCCDD``my-mod` |
### 查询参数(可选,用于过滤)
| 参数 | 类型 | 说明 | 示例 |
|------|------|------|------|
| `loaders` | `string` | 按加载器过滤JSON 数组字符串 | `'["fabric"]'` |
| `game_versions` | `string` | 按 Minecraft 版本过滤JSON 数组字符串 | `'["1.20.4"]'` |
| `featured` | `boolean` | 按是否精选过滤 | `true` |
| `include_changelog` | `boolean` | 是否在响应中包含 `changelog` 字段。**强烈建议设为 `false`** 以减小响应体,除非确实需要更新日志内容 | `false` |
### 请求示例
**获取某项目的全部版本(不含 changelog**
```bash
curl "https://api.modrinth.com/v2/project/AABBCCDD/version?include_changelog=false"
```
**按加载器和游戏版本过滤:**
```bash
curl "https://api.modrinth.com/v2/project/AABBCCDD/version?loaders=%5B%22fabric%22%5D&game_versions=%5B%221.20.4%22%5D"
```
> 注意:`loaders` 和 `game_versions` 的值需要是 JSON 数组字符串(如 `["fabric"]`),在 URL 中需要做 URL 编码。`[...]` 编码后为 `%5B...%5D`。
**Node.js (fetch) 示例:**
```js
const projectId = "AABBCCDD";
const url = new URL(`https://api.modrinth.com/v2/project/${projectId}/version`);
url.searchParams.set("include_changelog", "false");
const response = await fetch(url);
const versions = await response.json();
for (const v of versions) {
console.log(`版本名: ${v.name}`);
console.log(`版本号: ${v.version_number}`);
for (const f of v.files) {
console.log(` 文件: ${f.filename} (${f.size} bytes) ${f.primary ? "[主文件]" : ""}`);
}
}
```
---
## 接口二:获取单个版本
根据版本 ID 获取某个版本的完整信息。
| 项目 | 内容 |
|------|------|
| **端点** | `GET /version/{id}` |
| **认证** | 否(公开) |
| **成功响应码** | `200` |
| **响应体** | `Version` 对象 |
### 路径参数
| 参数 | 说明 | 示例 |
|------|------|------|
| `id` | 版本 ID8 位 base62 字符串) | `IIJJKKLL` |
### 请求示例
```bash
curl "https://api.modrinth.com/v2/version/IIJJKKLL"
```
```js
const versionId = "IIJJKKLL";
const response = await fetch(`https://api.modrinth.com/v2/version/${versionId}`);
const version = await response.json();
console.log(version.name, version.version_number);
```
---
## 接口三:通过项目 + 版本号获取版本
如果你知道项目 ID 和版本号(而非版本 ID可以用此接口直接获取。
| 项目 | 内容 |
|------|------|
| **端点** | `GET /project/{id\|slug}/version/{id\|number}` |
| **认证** | 否(公开) |
| **成功响应码** | `200` |
| **响应体** | `Version` 对象 |
### 路径参数
| 参数 | 说明 | 示例 |
|------|------|------|
| `id\|slug` | 项目 ID 或 slug | `AABBCCDD` |
| `id\|number` | 版本 ID 或版本号字符串 | `1.0.0``IIJJKKLL` |
> **注意:** 如果版本号匹配到多个版本,只会返回 **最旧的** 那个。建议使用版本 ID 获得精确结果。
### 请求示例
```bash
curl "https://api.modrinth.com/v2/project/AABBCCDD/version/1.0.0"
```
---
## 接口四:批量获取多个版本
一次请求获取多个指定版本的信息。
| 项目 | 内容 |
|------|------|
| **端点** | `GET /versions` |
| **认证** | 否(公开) |
| **成功响应码** | `200` |
| **响应体** | `Version[]` — Version 对象数组 |
### 查询参数
| 参数 | 类型 | 必填 | 说明 | 示例 |
|------|------|------|------|------|
| `ids` | `string` | ✅ | JSON 数组字符串,包含版本 ID 列表 | `'["IIJJKKLL", "MMNNOOPP"]'` |
### 请求示例
```bash
curl "https://api.modrinth.com/v2/versions?ids=%5B%22IIJJKKLL%22%2C%22MMNNOOPP%22%5D"
```
```js
const versionIds = ["IIJJKKLL", "MMNNOOPP"];
const url = new URL("https://api.modrinth.com/v2/versions");
url.searchParams.set("ids", JSON.stringify(versionIds));
const response = await fetch(url);
const versions = await response.json();
```
---
## 响应格式
### Version 对象结构
```json
{
"id": "IIJJKKLL",
"project_id": "AABBCCDD",
"author_id": "EEFFGGHH",
"name": "Version 1.0.0",
"version_number": "1.0.0",
"changelog": "## 更新内容\n\n- 修复了若干 Bug",
"date_published": "2025-01-01T00:00:00Z",
"downloads": 1024,
"version_type": "release",
"status": "listed",
"requested_status": null,
"game_versions": ["1.20.1", "1.20.4"],
"loaders": ["fabric"],
"featured": false,
"dependencies": [
{
"dependency_type": "required",
"project_id": "P7dR8mSH",
"version_id": null,
"file_name": null
}
],
"files": [
{
"hashes": {
"sha512": "93ecf5fe...",
"sha1": "c84dd4b3..."
},
"url": "https://cdn.modrinth.com/data/AABBCCDD/versions/1.0.0/my-mod-1.0.0.jar",
"filename": "my-mod-1.0.0.jar",
"primary": true,
"size": 1097270,
"file_type": null
},
{
"hashes": {
"sha512": "ab12cd34...",
"sha1": "ef56gh78..."
},
"url": "https://cdn.modrinth.com/data/AABBCCDD/versions/1.0.0/my-mod-1.0.0-sources.jar",
"filename": "my-mod-1.0.0-sources.jar",
"primary": false,
"size": 543210,
"file_type": "sources-jar"
}
]
}
```
### 关键字段说明
#### Version 顶层字段
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | `string` | 版本唯一 ID8 位 base62 |
| `project_id` | `string` | 所属项目 ID |
| `author_id` | `string` | 发布者用户 ID |
| `name` | `string` | **版本名称**(如 `"Version 1.0.0"` |
| `version_number` | `string` | **版本号**(如 `"1.0.0"`,建议遵循语义化版本) |
| `changelog` | `string \| null` | 更新日志文本(若使用 `include_changelog=false` 则为 `null` |
| `date_published` | `string` | 发布时间ISO-8601 格式) |
| `downloads` | `integer` | 下载次数 |
| `version_type` | `string` | 发布渠道:`release`、`beta`、`alpha` |
| `status` | `string` | 版本状态:`listed`、`archived`、`draft`、`unlisted`、`scheduled` |
| `game_versions` | `string[]` | 支持的 Minecraft 版本列表 |
| `loaders` | `string[]` | 支持的加载器列表 |
| `featured` | `boolean` | 是否为精选版本 |
| `dependencies` | `object[]` | 依赖列表(结构见下方) |
| `files` | `object[]` | 该版本的所有文件列表 |
#### dependencies 数组项
| 字段 | 类型 | 说明 |
|------|------|------|
| `dependency_type` | `string` | `required`、`optional`、`incompatible`、`embedded` |
| `project_id` | `string \| null` | 依赖的项目 ID |
| `version_id` | `string \| null` | 依赖的具体版本 ID |
| `file_name` | `string \| null` | 依赖文件名 |
#### files 数组项(最常需要关注的字段)
| 字段 | 类型 | 说明 |
|------|------|------|
| `filename` | `string` | **文件名**(如 `"my-mod-1.0.0.jar"` |
| `url` | `string` | 文件直链下载地址 |
| `size` | `integer` | 文件大小(字节) |
| `primary` | `boolean` | 是否为主文件。每个版本最多一个主文件;若没有一个标记为 `true`,则推断第一个文件为主文件 |
| `hashes.sha1` | `string` | 文件的 SHA-1 哈希 |
| `hashes.sha512` | `string` | 文件的 SHA-512 哈希 |
| `file_type` | `string \| null` | 文件类型:`sources-jar`、`dev-jar`、`javadoc-jar`、`required-resource-pack`、`optional-resource-pack`、`unknown`、`signature`。普通主 jar 为 `null` |
---
## 常见使用场景
### 场景 1获取项目的最新版本
从版本列表中取第一个(通常是时间最新的),再拿到文件信息:
```js
const projectSlug = "my-mod";
const response = await fetch(
`https://api.modrinth.com/v2/project/${projectSlug}/version?include_changelog=false`
);
const versions = await response.json();
const latest = versions[0];
console.log(`版本: ${latest.name} (${latest.version_number})`);
console.log(`主文件: ${latest.files.find(f => f.primary).filename}`);
```
### 场景 2列出某版本的所有文件及其类型
```js
const versionId = "IIJJKKLL";
const response = await fetch(`https://api.modrinth.com/v2/version/${versionId}`);
const version = await response.json();
for (const file of version.files) {
const typeLabel = file.file_type ?? "主 jar";
console.log(`[${typeLabel}] ${file.filename}${file.url}`);
}
```
输出示例:
```
[主 jar] my-mod-1.0.0.jar — https://cdn.modrinth.com/.../my-mod-1.0.0.jar
[sources-jar] my-mod-1.0.0-sources.jar — https://cdn.modrinth.com/.../my-mod-1.0.0-sources.jar
```
### 场景 3下载版本的主文件通过直链
```js
const version = await fetch("https://api.modrinth.com/v2/version/IIJJKKLL").then(r => r.json());
const primaryFile = version.files.find(f => f.primary) ?? version.files[0];
const fileBuffer = await fetch(primaryFile.url).then(r => r.arrayBuffer());
require("fs").writeFileSync(primaryFile.filename, Buffer.from(fileBuffer));
```
### 场景 4仅获取特定加载器 + 游戏版本的版本
```js
const projectId = "AABBCCDD";
const url = new URL(`https://api.modrinth.com/v2/project/${projectId}/version`);
url.searchParams.set("loaders", JSON.stringify(["fabric"]));
url.searchParams.set("game_versions", JSON.stringify(["1.20.4"]));
url.searchParams.set("include_changelog", "false");
const versions = await fetch(url).then(r => r.json());
for (const v of versions) {
console.log(`${v.name} (${v.version_number}) — ${v.files.find(f => f.primary)?.filename}`);
}
```
---
## 错误码
| 状态码 | 说明 |
|--------|------|
| `200` | 成功 |
| `404` | 项目不存在、版本不存在,或无权访问(如草稿版本) |
---
## 注意事项与最佳实践
### 1. 始终使用 `include_changelog=false`
除非你真的需要每个版本的 changelog 文本,否则务必传入 `include_changelog=false`。changelog 可能非常长会显著增大响应体、降低请求速度。Modrinth 官方也强烈建议这样做。
### 2. 主文件的判断规则
`files` 数组中若有一个 `primary: true`,那就是主文件。如果一个都没有,则**推断第一个文件为主文件**。不要假定 `files[0]` 一定是主 jar——sources jar 也可能排在首位。
### 3. 版本列表的排序
`GET /project/{id|slug}/version` 返回的列表**按发布日期降序排列**(最新的在前)。若需确定顺序,请以 `date_published` 字段为准。
### 4. 别忘了 User-Agent
即使是公开 GET 请求Modrinth 也要求设置 `User-Agent` 请求头:
```
User-Agent: your_username/your_project/1.0.0 (contact@example.com)
```
### 5. 通过 slug 访问更易读
项目标识符支持 slug`my-mod`)而非只能用 ID`AABBCCDD`),对于调试和可读性更有帮助。但 slug 可能被项目所有者修改,长期存储建议使用 ID。
### 6. 版本号可能不唯一
`GET /project/{id|slug}/version/{id\|number}` 在使用版本号查找时,若遇到重名只返回最旧的那个。精确获取请使用版本 ID。
### 7. 分页
`GET /project/{id|slug}/version` **不支持分页参数**,会一次性返回该项目所有版本。对于版本数量极多的项目,响应体可能较大,此时推荐结合 `loaders``game_versions` 过滤。
---
## 可用加载器与游戏版本查询
如果你不确定 `loaders``game_versions` 过滤参数应填什么值,可以通过标签接口查询所有合法值:
```bash
curl "https://api.modrinth.com/v2/tag/loader"
curl "https://api.modrinth.com/v2/tag/game_version"
```
---
## 参考
- [Modrinth API 文档](https://docs.modrinth.com)
- [OpenAPI 规范文件](openapi.yml)
- [新建版本 API 文档](upload.md)