Redmine API¶
Redmine 通过 REST API 提供部分数据。此 API 提供了对以下资源的基本 CRUD 操作(创建、更新、删除)的访问。API 支持以下格式:XML 和 JSON。
API 描述¶
| 资源 | 状态 | 注释 | 可用性 |
|---|---|---|---|
| 问题 | 稳定 | 1.0 | |
| 项目 | 稳定 | 1.0 | |
| 项目成员 | alpha | 1.4 | |
| 用户 | 稳定 | 1.1 | |
| 时间条目 | 稳定 | 1.1 | |
| 新闻 | 原型 | 仅为 index 的原型实现 |
1.1 |
| 问题关系 | alpha | 1.3 | |
| 版本 | alpha | 1.3 | |
| 维基页面 | alpha | 2.2 | |
| 查询 | alpha | 1.3 | |
| 附件 | beta | 通过 API 添加附件(1.4) | 1.3 |
| 问题状态 | alpha | 提供所有状态列表 | 1.3 |
| 跟踪器 | alpha | 提供所有跟踪器列表 | 1.3 |
| 枚举 | alpha | 提供问题优先级和时间跟踪活动列表 | 2.2 |
| 问题类别 | alpha | 1.3 | |
| 角色 | alpha | 1.4 | |
| 组 | alpha | 2.1 | |
| 自定义字段 | alpha | 2.4 | |
| 搜索 | alpha | 3.3 | |
| 文件 | alpha | 3.4 | |
| 我的账户 | alpha | 4.1 | |
| 日志 | alpha | 5.0 |
状态图例
- 稳定 - 功能完善,没有计划进行重大更改
- beta - 可用于集成,存在一些错误或缺少一些功能
- alpha - 放置了主要功能,需要 API 用户和集成商的反馈
- 原型 - 非常粗略的实现,版本中可能存在重大破坏性更改。 不推荐用于集成
- 计划 - 计划在未来的版本中,取决于开发者的可用性
您可以查看每个版本的 API 变更列表。
一般主题¶
在 POST/PUT 请求中指定 Content-Type¶
当创建或更新远程元素时,请求的 Content-Type 必须 指定,即使远程 URL 有相应的后缀(例如 POST ../issues.json)- 对于 JSON 内容,必须设置为
Content-Type: application/json。 - 对于 XML 内容,设置为
Content-Type: application/xml。
身份验证¶
大多数情况下,API需要身份验证。要启用API风格的身份验证,您必须在“管理”->“设置”->“API”中检查“启用REST API”。然后,可以通过两种不同的方式进行身份验证:- 通过HTTP基本身份验证使用您的常规登录名/密码。
- 使用您的API密钥,这是一种避免在脚本中放置密码的便捷方法。API密钥可以按照以下方式之一附加到每个请求中:
- 作为“key”参数传递
- 作为通过HTTP基本身份验证的随机密码的用户名传递
- 作为“X-Redmine-API-Key”HTTP头(从Redmine 1.1.0开始添加)
您可以在登录后找到您的API密钥(/my/account),在默认布局的右侧面板中。
用户伪装¶
从Redmine 2.2.0开始,您可以通过设置API请求的X-Redmine-Switch-User头来伪装用户。它必须设置为用户登录名(例如X-Redmine-Switch-User: jsmith)。这仅在您使用管理员账户的API时有效,当使用常规用户账户的API时,此头将被忽略。
如果使用X-Redmine-Switch-User头指定的登录名不存在或未激活,您将收到一个412错误响应。
集合资源和分页¶
对集合资源(例如/issues.xml,/users.xml)的GET请求的响应通常不会返回您数据库中可用的所有对象。Redmine 1.1.0引入了一种使用以下参数查询此类资源的通用方式:
offset:要检索的第一个对象的偏移量limit:响应中应包含的项目数(默认值为25,最大值为100)
示例
GET /issues.xml => returns the 25 first issues GET /issues.xml?limit=100 => returns the 100 first issues GET /issues.xml?offset=30&limit=10 => returns 10 issues from the 30th
对集合资源的GET请求的响应提供了关于Redmine中可用的总对象计数以及用于响应的偏移量和限制的信息。示例
GET /issues.xml <issues type="array" total_count="2595" limit="25" offset="0"> ... </issues>
GET /issues.json
{ "issues":[...], "total_count":2595, "limit":25, "offset":0 }
注意:如果您正在使用不支持此类顶级属性(total_count、limit、offset)的REST客户端,您可以将nometa参数或X-Redmine-NometaHTTP头设置为1,以获取不带它们的响应。示例
GET /issues.xml?nometa=1 <issues type="array"> ... </issues>
获取关联数据¶
从1.1.0版本开始,您必须通过将include参数附加到查询URL中显式指定您想要包含在查询结果中的关联
示例
检索带有描述的issue日志
GET /issues/296.xml?include=journals <issue> <id>296</id> ... <journals type="array"> ... </journals> </issue>
您还可以使用以逗号分隔的项目列表加载多个关联。
示例
GET /issues/296.xml?include=journals,changesets <issue> <id>296</id> ... <journals type="array"> ... </journals> <changesets type="array"> ... </changesets> </issue>
处理自定义字段¶
大多数Redmine对象支持自定义字段。它们的值可以在custom_fields属性中找到。
XML示例
GET /issues/296.xml # an issue with 2 custom fields
<issue>
<id>296</id>
...
<custom_fields type="array">
<custom_field name="Affected version" id="1">
<value>1.0.1</value>
</custom_field>
<custom_field name="Resolution" id="2">
<value>Fixed</value>
</custom_field>
</custom_fields>
</issue>
JSON示例
GET /issues/296.json # an issue with 2 custom fields
{"issue":
{
"id":8471,
...
"custom_fields":
[
{"value":"1.0.1","name":"Affected version","id":1},
{"value":"Fixed","name":"Resolution","id":2}
]
}
}
您还可以在创建/更新对象时使用相同的语法(除了自定义字段名称不是必需的)来设置/更改自定义字段的值。
XML示例
PUT /issues/296.xml
<issue>
<subject>Updating custom fields of an issue</subject>
...
<custom_fields type="array">
<custom_field id="1">
<value>1.0.2</value>
</custom_field>
<custom_field id="2">
<value>Invalid</value>
</custom_field>
</custom_fields>
</issue>
注意:custom_fields XML标签上的type="array"属性是严格必需的。
JSON示例
PUT /issues/296.json
{"issue":
{
"subject":"Updating custom fields of an issue",
...
"custom_fields":
[
{"value":"1.0.2","id":1},
{"value":"Invalid","id":2}
]
}
}
附加文件¶
通过REST API添加附件的支持是在Redmine 1.4.0中添加的。
首先,您需要通过向/uploads.xml(或/uploads.json)发送POST请求上传每个文件。请求正文应该是您想要附加的文件的内容,并且Content-Type头必须设置为application/octet-stream(否则您将收到一个406 Not Acceptable响应)。如果上传成功,您将收到一个包含上传文件令牌的201响应。
然后您可以使用此令牌将上传的文件附加到新或现有的问题上。
XML示例
首先,上传您的文件
POST /uploads.xml?filename=image.png Content-Type: application/octet-stream ... (request body is the file content) # 201 response <upload> <token>7167.ed1ccdb093229ca1bd0b043618d88743</token> </upload>
然后使用上传令牌创建问题
POST /issues.xml
<issue>
<project_id>1</project_id>
<subject>Creating an issue with a uploaded file</subject>
<uploads type="array">
<upload>
<token>7167.ed1ccdb093229ca1bd0b043618d88743</token>
<filename>image.png</filename>
<description>An optional description here</description>
<content_type>image/png</content_type>
</upload>
</uploads>
</issue>
如果您尝试上传超过允许的最大大小的文件,您将收到一个422响应
POST /uploads.xml?filename=image.png Content-Type: application/octet-stream ... (request body larger than the maximum size allowed) # 422 response <errors> <error>This file cannot be uploaded because it exceeds the maximum allowed file size (1024000)</error> </errors>
JSON示例
首先,上传您的文件
POST /uploads.json?filename=image.png
Content-Type: application/octet-stream
...
(request body is the file content)
# 201 response
{"upload":{"token":"7167.ed1ccdb093229ca1bd0b043618d88743"}}
然后使用上传令牌创建问题
POST /issues.json
{
"issue": {
"project_id": "1",
"subject": "Creating an issue with a uploaded file",
"uploads": [
{"token": "7167.ed1ccdb093229ca1bd0b043618d88743", "filename": "image.png", "content_type": "image/png"}
]
}
}
您还可以上传多个文件(通过向/uploads.json发送多个POST请求),然后创建带有多个附件的问题
POST /issues.json
{
"issue": {
"project_id": "1",
"subject": "Creating an issue with a uploaded file",
"uploads": [
{"token": "7167.ed1ccdb093229ca1bd0b043618d88743", "filename": "image1.png", "content_type": "image/png"},
{"token": "7168.d595398bbb104ed3bba0eed666785cc6", "filename": "image2.png", "content_type": "image/png"}
]
}
}
验证错误¶
当尝试创建或更新具有无效或缺失属性参数的对象时,您将收到422 Unprocessable Entity响应。这意味着对象无法创建或更新。在这种情况下,响应体包含相应的错误消息
XML示例:
# Request with invalid or missing attributes POST /users.xml <user> <login>john</login> <lastname>Smith</lastname> <mail>john</mail> </uer> # 422 response with the error messages in its body <errors type="array"> <error>First name can't be blank</error> <error>Email is invalid</error> </errors>
JSON示例:
# Request with invalid or missing attributes
POST /users.json
{
"user":{
"login":"john",
"lastname":"Smith",
"mail":"john"
}
}
# 422 response with the error messages in its body
{
"errors":[
"First name can't be blank",
"Email is invalid"
]
}
JSONP支持¶
Redmine 2.1.0+ API支持JSONP,以便在不同的域名(例如,使用JQuery)的Redmine服务器中请求数据。回调可以通过callback或jsonp参数传递。从Redmine 2.3.0版本开始,JSONP支持是可选的,默认情况下是禁用的,您可以通过在“管理” -> “设置” -> “API”中勾选“启用JSONP支持”来启用它。
示例
GET /issues.json?callback=myHandler
myHandler({"issues":[ ... ]})
各种语言/工具中的API使用¶
API变更历史¶
本节列出了可能破坏向后兼容性的现有API功能更改。API的新功能请参阅API描述。
2012-01-29:多选自定义字段(r8721,1.4.0)¶
Redmine现在支持具有多个值的自定义字段,并在API响应中可以找到。这些自定义字段具有multiple=true属性,其value属性是一个数组。
示例
GET /issues/296.json
{"issue":
{
"id":8471,
...
"custom_fields":
[
{"value":["1.0.1","1.0.2"],"multiple":true,"name":"Affected version","id":1},
{"value":"Fixed","name":"Resolution","id":2}
]
}
}