API 基础知识
Adobe Workfront API的目标是通过引入通过HTTP运行的REST-ful架构来简化与Workfront的集成。 本文档假设您熟悉REST和JSON响应,并介绍了Workfront API采用的方法。
熟悉Workfront架构将有助于了解可用于从Workfront中提取数据以进行集成的数据库关系。
限制和准则
为了确保一致的Workfront按需系统性能,Workfront API限制并发API线程。 此护栏可防止由滥用API调用导致的系统问题。 沙盒环境已达到相同的并发API线程限制,允许客户和合作伙伴在将代码发布到生产环境之前准确测试API调用。
对于生产、预览和测试驱动器环境,最终用户请求的最大URI长度为8892字节,因为它们是通过Workfront CDN (Akamai)路由的。 此限制仅适用于通过CDN路由的URI。
免责声明
对API的任何使用都应当在Workfront测试版环境中进行测试,然后再在生产环境中运行。 如果任何客户将API用于Workfront有理由认为对按需软件造成负担的流程(即,该流程会对其他客户的软件性能产生重大负面影响),Workfront将保留请求客户停止该流程的权利。 如果客户不遵守管理法规且问题仍然存在,Workfront将保留终止该流程的权利。
WORKFRONT API URL
有关将用于调用Workfront API的URL的信息,请参阅Adobe Workfront API调用的域格式。
REST基础知识
本节简要介绍如何与以下REST原则的Workfront REST API交互:
对象URI
系统中的每个对象都有一个由对象类型和ID组成的唯一URI。 以下示例显示描述三个唯一对象的URI:
/attask/api/v15.0/project/4c78821c0000d6fa8d5e52f07a1d54d0
/attask/api/v15.0/task/4c78821c0000d6fa8d5e52f07a1d54d1
/attask/api/v15.0/issue/4c78821c0000d6fa8d5e52f07a1d54d2
对象类型不区分大小写,可以是缩写的ObjCode(如proj)或替代对象名称(project)。
有关对象、有效ObjCode和对象字段的列表,请参见 API资源管理器。
Category
对象,自定义字段是Parameter
对象。运营
通过将HTTP请求发送到对象的唯一URI来控制对象。 要执行的操作由HTTP方法指定。
标准HTTP方法对应于以下操作:
- GET — 按ID检索对象、按查询搜索所有对象、运行报告或执行命名查询
- POST — 插入新对象
- PUT — 编辑现有对象
- DELETE — 删除对象
为了解决客户端缺陷或协议长度限制,可以使用方法参数覆盖HTTP行为。 例如,可以通过发布以下URI来实现GET操作:
GET/attask/api/v15.0/project?id=4c78...54d0&method=get
GET/attask/api/v15.0/project/4c78...54d0?method=get
响应
每个请求都会以JSON格式获得响应。 如果请求成功,响应将具有data属性;如果存在问题,则响应将具有error属性。 例如,请求
GET /attask/api/v15.0/proj/4c7c08b20000002de5ca1ebc19edf2d5
返回类似于以下内容的JSON响应:
{
"data": [
{
"percentComplete": 0,
"status": "CUR",
"priority": 2,
"name": "Brand New Project",
"ID": "4c7c08b20000002de5ca1ebc19edf2d5"
}
]
已围绕PUT、POST和DELETE请求添加了特殊安全性。 只有在URI中包含 sessionID=abc123 时,才能执行导致写入数据库或从数据库中删除的任何请求。 以下示例显示了如何查找DELETE请求:
GET/attask/api/v15.0/project?id=4c78...54d0&method=delete&sessionID=abc123
GET/attask/api/v15.0/project/4c78...54d0?method=delete&sessionID=abc123
身份验证
API对每个请求进行身份验证,以确保客户端有权查看或修改请求的对象。
身份验证是通过传入会话ID执行的,会话ID可通过以下方法之一提供:
请求标头身份验证
首选的身份验证方法是传递包含会话令牌的名为SessionID的请求标头。 这样可以安全地抵御跨站点请求伪造(CSRF)攻击,并且不会出于缓存目的干扰URI。
以下是请求标头的示例:
GET /attask/api/v15.0/project/search
SessionID: abc1234
请求参数身份验证
您可以通过传递名为sessionID的请求参数来进行身份验证,如以下示例所示:
GET /attask/api/v15.0/project/4c78821c0000d6fa8d5e52f07a1d54d0?sessionID=abc1234
基于Cookie的身份验证
该API使用的基于Cookie的身份验证与Web UI用于系统的身份验证相同。 其中,如果客户端使用Web UI登录到Workfront,则从同一浏览器中进行的任何AJAX调用都使用相同的身份验证。
登录
/login
端点或API密钥。 请改用以下身份验证方法之一:- 使用JWT进行服务器身份验证
- 使用OAuth2进行用户身份验证
使用有效的用户名和密码,您可以使用以下请求获取会话ID:
POST /attask/api/v15.0/login?username=admin&password=user
这将设置一个Cookie以对未来的请求进行身份验证,并返回具有新创建的会话ID、登录用户的用户ID和其他会话属性的JSON响应。
生成API密钥
您可以以该用户身份登录系统时生成API密钥,如以下示例所示:
PUT /attask/api/v15.0/user?action=generateApiKey&username= username&password=password&method=put
检索先前生成的API密钥
您还可以通过运行getApiKey检索之前为特定用户生成的API密钥:
PUT /attask/api/v15.0/user?action=getApiKey&username=user@email.com&password=userspassword&method=put
然后,您可以使用此结果通过添加“apiKey”作为请求参数来验证任何API调用,使用该值替换sessionID或用户名和密码。 从安全角度来看,这是有益的。
以下请求是使用apiKey从项目检索数据的示例:
GET /attask/api/v15.0/project/abc123xxxxx?apiKey=123abcxxxxxxxxx
使API密钥失效
如果apiKey值已泄漏,您可以运行“clearApiKey”,以使当前API密钥失效,如以下示例所示:
GET /attask/api/v15.0/user?action=clearApiKey&username=user@email.com&password=userspassword&method=put
清除后,您可以再次运行getApiKey以生成新的API密钥。
注销
会话完成后,您可以使用以下请求将用户注销,从而防止进一步使用sessionID进行访问。
GET /attask/api/v15.0/logout?sessionID=abc1234
要注销的sessionID可指定为Cookie、请求标头或请求参数。
注销用户:
-
导航到登录屏幕,但不登录。
-
将URL更改为/attask/api/v15.0/project/search。
请注意,找不到该页面。 -
将 搜索 一词替换为login?username=admin&password=user,将您的用户名和密码替换为 admin 和*user
*此会话将作为Cookie存储在浏览器中,无需在每次后续GET请求中重述。 -
将URL更改回 /attask/api/v15.0/project/search。
-
请注意提供的响应。
执行PUT、POST和DELETE请求时,必须始终包含登录后提供的sessionID。
GET行为
使用HTTPGET方法检索一个或多个对象并运行报表。
正在检索对象
您可以使用修饰符和过滤器来增强对对象的搜索。
使用对象ID检索对象
如果您知道对象的ID,则可以通过访问对象的唯一URI来检索该对象。 例如,请求
GET /attask/api/v15.0/project/4c78821c0000d6fa8d5e52f07a1d54d0
返回类似于以下内容的响应:
{
"percentComplete": 0,
"status": "CUR",
"priority": 2,
"name": "Brand New Project",
"ID": "4c7c08b20000002de5ca1ebc19edf2d5"
}
您可以通过指定id请求参数并提供以逗号分隔的ID列表来检索同一请求中的多个对象,如以下示例所示:
GET /attask/api/v15.0/project?id=4c78...54d0,4c78...54d1
请注意/attask/api/v15.0/project?id=…请求与/attask/api/v15.0/project/...
请求相同。
使用URI检索对象
如果要按ID以外的标准检索对象,则可以搜索URI。
例如,您可以使用以下请求返回系统中所有项目的列表:
GET /attask/api/v15.0/project/search
您可以使用请求参数作为名称 — 值对来指定过滤器。 例如,以下示例显示一个可查找所有当前项目的请求:
GET /attask/api/v15.0/project/search?status=CUR
以下请求查找所有尚未完成并且已分配给名为John的用户的任务。
GET /attask/api/v15.0/task/search?percentComplete=100
&percentComplete_Mod=lt &assignedTo:firstName=John
使用搜索修饰符
下表列出了您可以与Workfront API一起使用的一些修饰符。
…status=cls&status_Mod=eq…
…status=cls&status_Mod=ne…
…percentComplete=50&percentComplete_Mod=gte…
…percentComplete=50&percentComplete_Mod=lte…
…description_Mod=isnull…
…description_Mod=notnull…
…name=Workfront&name_Mod=contains…
…entryDate=$$TODAY-7d&entryDate_Range=$$TODAY&entryDate_Mod=between…
使用OR语句
您可以通过添加包含“OR”的参数以及数字来增强搜索,以指示过滤器或一系列过滤器的级别。
OR语句仅返回API调用中符合OR语句筛选条件的记录。 OR语句级别上并不隐含过滤器。
例如,如果要筛选
- 名称中包含“Planning”或
- 名为“FixedAssets”且分配给名称包含“Steve”OR的人员的项目组合中的任务
- 具有名为“最终任务”的父任务的任务
然后,将以下API调用与其多个OR语句一起使用:
GET/attask/api/v15.0/task/search?name=Planning
&name_Mod=contains
&OR:1:portfolio:name=FixedAssets
&OR:1:portfolio:name_Mod=eq
&OR:1:assignedTo:name=Steve
&OR:1:assignedTo:name_Mod=cicontains
&OR:2:parent:name=Final Task
&OR:2:父项:name_Mod =eq
使用过滤器参数
为搜索过滤器使用URL参数时存在的一个潜在隐患是,Workfront会先解析某些参数,然后再检查是否存在其他身份验证方法(即,用户名、密码、apiKey、Cookie)。 如果发生这种情况,则在调用中不会将参数用作过滤器。
要避免出现此问题,您可以将这些值放入带有JSON格式的过滤器参数中。 例如,如果要筛选用户名testuser,而不使用
/attask/api/v15.0/user/search?username=testuser@workfront.com
/attask/api/v15.0/user/search?filters={"username":"testuser@workfront.com"}
使用映射请求参数
默认情况下,从搜索返回的数据是JSON数组。 根据您的用例,将结果作为JSON对象按ID索引可能会更有效。 可以使用map请求参数完成此操作。 例如,请求
/attask/api/v15.0/task/search?map=true
{
"data": {
“4c9a97db0000000f13ee4446b9aead9b”: {
"percentComplete": 0,
"status": "NEW",
"name": "first task",
"ID": "4c9a97db0000000f13ee4446b9aead9b",
"taskNumber": 1
},
“4ca28ba600002024cd49e75bd43cf601”: {
"percentComplete": 0,
"status": "INP:A",
"name": "second task",
"ID": "4ca28ba600002024cd49e75bd43cf601",
"taskNumber": 2
}
}
}
使用字段请求参数
默认情况下,检索对象仅返回最常用的字段子集。
您可以使用字段请求参数指定返回的特定字段的逗号分隔列表。 例如,请求
/attask/api/v15.0/task/search?fields=plannedStartDate,priority
{
"priority": 2,
"name": "first task",
"ID": "4c7c08fa0000002ff924e298ee148df4",
"plannedStartDate": "2010-08-30T09:00:00:000-0600"
}
有关可能的字段引用的列表,请参见 API资源管理器
搜索嵌套对象
可以搜索嵌套对象。 默认情况下,返回嵌套对象时只包含名称和ID。 例如,要了解所有问题及其所有者,请使用以下请求:
/attask/api/v15.0/issue/search?fields=owner
/attask/api/v15.0/issue/search?fields=owner:title,owner:phoneNumber
{
"name": "a important issue",
"ID": "4c78285f00000908ea8cfd66e084939f",
“所有者”: {
"title": "Operations Specialist",
"phoneNumber": "555-1234",
"name": "Admin User",
"ID": "4c76ed7a0000054c172b2c2d9f7f81c3"
}
}
检索嵌套收藏集
您可以检索嵌套的对象集合。 例如,要获取项目及其所有任务,请使用以下请求:
/attask/api/v15.0/project/search?fields=tasks
/attask/api/v15.0/task/search?fields=assignments
搜索多个嵌套字段
默认情况下,仅返回每个任务的名称和ID,但可以使用冒号语法指定其他嵌套字段。 要查看相关对象或收藏集的所有可用字段,只需在对象/收藏集引用中附加冒号和星号即可。
/attask/api/v15.0/task/search?fields=assignments:*
检索自定义数据
您可以使用前缀“DE:”检索自定义数据字段。 例如,要请求具有名为“CustomText”的参数的项目,请使用以下请求:
/attask/api/v15.0/project/search?fields=DE:CustomText
{
"name": "custom data project",
"ID": "4c9a954f0000001afad0687d7b1b4e43",
"DE:CustomText": "任务b"
}
/attask/api/v15.0/project/search?fields=parameterValues
{
"name": "custom data project",
"ID": "4c9a954f0000001afad0687d7b1b4e43",
parameterValues: {
"DE:CustomText": "任务b",
"DE:CustomNumber": 1.4,
"DE:CustomCheckBoxes":["first", "second", "third"]
}
使用命名查询
某些对象类型具有通常执行的命名搜索,可以通过将查询名称附加到对象类型URI的末尾来提供。 例如,以下请求可检索用户当前已分配的工作项(任务和问题):
/attask/api/v15.0/work/myWork
使用Count
您可以使用count
返回与查询匹配的结果数。 当您不需要结果中的数据时,这可能很有用。 通过只返回计数,服务器可以更快地处理请求并节省带宽。 例如,请求
GET/attask/api/v15.0/project/count?status=CUR
{
"count": 3
}
请求报告
您可以执行报表请求,其中只需要一个或多个分组的某些字段的汇总。 如以下示例所示,报表语法与SOAP API的语法相同:
GET/attask/api/v15.0/hour/report?project:name_1_GroupBy=true&hours_AggFunc=sum
{
“第一个项目”: {
"sum_hours": 15
},
“第二个项目”: {
"sum_hours": 30
}
{
“第一个项目”: {
"sum_hours": 15
},
“第二个项目”: {
"sum_hours": 30
},
"$$ROLLUP": {
"sum_hours": 45
}
}
在API中对查询结果进行排序
如果将以下内容附加到API调用,则可以按任何字段对结果进行排序:
&entryDate_Sort=asc
例如,如果要按任务计划开始日期排序,请删除entryDate并将其替换为plannedCompletionDate。
这适用于Workfront中的大多数字段。
考虑查询限制
查询对象时,应特别考虑相关对象之间的关系和搜索限制。 例如,如下表所示,项目查询最多可返回2,000个项目。 这2,000个项目被视为“主要对象”。 如果您在项目中查询“任务”字段,则作为集合的“任务”字段将成为主对象“项目”的辅助对象。 “任务”字段的查询可包含项目中的数千个任务。 返回的对象(项目和任务)的总数不能超过50,000的最大值。
为确保获得最佳性能,下表显示了对搜索请求的限制。
使用分页响应 using-paginated-responses
要覆盖“默认结果数”查询限制并允许200个结果,您可以在查询中包含$$LIMIT=200
筛选器,如以下示例所示:
GET/attask/api/v15.0/project/search?$$LIMIT=200
为确保系统中其他租户的可靠性和性能,每个查询允许的最大结果限制为2000个对象。 尝试指定更大的限制将导致IllegalArgumentException
错误消息。
因此,我们建议您考虑对大型数据集使用分页响应。 要指定应返回的第一个结果,请添加$$FIRST
筛选器。 例如,以下请求为查询返回结果201-250:
GET/attask/api/v15.0/project/search?$$FIRST=200&$$LIMIT=50
请注意,在上例中,$$FIRST=200
返回第201个结果。 $$FIRST=0
将返回第一个结果。 将$$FIRST值视为返回结果之前要跳过的结果数可能会有所帮助。
要确保结果正确分页,请使用排序参数。 这样可按相同顺序返回结果,以便分页不会重复或跳过结果。 例如,要使用对象ID进行排序,请使用ID_Sort=asc
。
创建访问规则
您可以创建访问规则以确定谁可以访问对象。 以下是您可以设置的访问规则的示例:
要设置项目以便仅与ID为“abc123”的用户共享,请使用以下请求:
GET/attask/api/v15.0/project/123abcxxxxxxxxxxxxxxxxxxxxxx?method=put &updates={ accessRules: [ {accessorID: 'abc123', accessorObjCode: 'USER', coreAction: 'VIEW'} ] }
GET/attask/api/v15.0/project/123abcxxxxxxxxxxxxxxxxxxxxxx/share?method=put&accessorID=abc123&accessorObjCode=USER&coreAction=VIEW
GET/attask/api/v15.0/project/123abcxxxxxxxxxxxxxxxxxxxxxxxx?fields=accessRules:*
POST行为
POST插入新对象。 语法与PUT相同,但有一些例外。 由于新对象尚不存在,因此它没有ID。 因此,URI不包括ID。
创建对象
以下是创建新项目的请求示例:
POST/attask/api/v15.0/project?name=新建项目
复制对象
某些对象支持被复制。 对于这些对象类型,可以通过使用copySourceID参数发布来创建新对象。 例如,以下请求复制给定项目并为其提供一个新名称:
POST /attask/api/v15.0/project?copySourceID=4c7...&name=Copied Project
上传文档
您可以通过以下API URL上传文档:
POST/attask/api/v15.0/upload
{
"handle": "4c7c08fa0000002ff924e298ee148df4"
}
POST/attask/api/v15.0/document?updates={
} 名称: aFileName,
句柄: abc...123,(来自文件上载的句柄)
docObjCode: PROJ,(或TASK、OPTASK等)
对象ID: abc...123,
currentVersion:{version:v1.0,文件名:aFileName}
PUT行为
PUT用于更新现有对象。
PUT的响应与GET相同。 在这两种情况下,服务器都会在更新后返回对象的新状态。 所有用于更改对GET请求的响应的规则也可用于PUT,例如指定要返回的其他字段、自定义数据等。
编辑对象
对象的更新始终使用对象的唯一URI通过ID完成。 要更新的字段被指定为请求参数。 例如,要更改项目的名称,您可以发送类似于以下内容的请求:
PUT/attask/api/v15.0/project/4c7...?name=新项目名称
PUT/attask/api/v15.0/project?id=4c7...&name=新项目名称
指定JSON编辑
如以下示例所示,您可以使用更新请求参数指定要使用JSON语法更新的字段:
PUT/attask/api/v15.0/project/4c7...?更新=
{
名称:“新项目名称”,
状态:“CUR”,
...
}
进行嵌套更新
某些对象具有可以更新的私有集合。 例如,以下示例演示了如何覆盖给定任务的现有分配:
PUT/attask/api/v15.0/task/4c7...?更新=
{
工作: [
{
assignedToID: "2222...54d0,
assignmentPercent: 50.0
},{
roleID: "1111...54d0"
}
]
以下示例将项目设为公共技术支持队列。 请注意,现有队列属性将被替换。
PUT/attask/api/v15.0/project/4c7...?更新=
{
queueDef: {
isPublic: 1
}
}
使用操作请求参数
除了简单的编辑之外,某些对象还支持可以执行的其他操作。 您可以使用操作请求参数指定这些操作。 例如,以下请求重新计算给定项目的时间线:
PUT/attask/api/v15.0/project/4c7...?action=calculateTimeline
或
PUT/attask/api/v15.0/project/4c7.../calculateTimeline
移动对象
下面演示了将任务从一个项目移动到另一个项目的语法:
PUT/attask/api/v15.0/task/4c7.../move?projectID=5d8...
PUT/attask/api/v15.0/project/1234/approveApproval
PUT/attask/api/v15.0/project/1234/calculateFinance
PUT/attask/api/v15.0/project/1234/calculateTimeline
PUT/attask/api/v15.0/project/1234/calculateDataExtension
PUT/attask 4/recallApproval
PUT/attask/api/v15.0/project/1234/rejectApproval
PUT/attask/api/v15.0/task/1234/move
PUT/attask/api/v15.0/workitem/1234/markViewed
以下是每种操作类型的示例:
PUT/attask/api/v15.0/project/1234?method=put&updates={accessRules:[{accessorID: 'abc123', accessorObjCode: 'USER', coreAction: 'VIEW'}]}
共享对象
以下示例演示了与团队共享项目的语法:
PUT/attask/api/v15.0/project/123abcxxxxxxxxxxxxxxxxxxxxxxxx/share?accessorID=123abcxxxxxxxxxxxxxxxxxxxxxx&accessorObjCode=TEAMOB
PUT/attask/api/v15.0/project/123abcxxxxxxxxxxxxxxxxxxxxxxxx?method=PUT&updates={accessRules:[{accessorID:'123abcxxxxxxxxxxxxxxxxxxxxxxxxxx',accessorObjCode:'TEAMOB',coreAction:'VIEW'}]
PUT/attask/api/v15.0/task/4c7.../move?projectID=5d8...
DELETE行为
DELETE删除对象。 在每种情况下,URI都可以包含参数force=true ,以促使服务器删除指定的数据及其依赖项。 在以下示例中,通过在URI上执行HTTPDELETE方法删除任务:
DELETE/attask/api/v15.0/task/4c78821c000d6fa8d5e52f07a1d54d0
DELETE/attask/api/v15.0/task?id=4c78821c0000d6fa8d5e52f07a1d54d0
DELETE/attask/api/v15.0/task/4c78821c0000d6fa 5e52f07a1d54d0?force=true
DELETE/attask/api/v15.0/task?id=4c78821c0000d6fa8d5e52f07a1d54d0?force=true
批量更新
批量更新语句在单次API调用中同时更新多个对象。 批量创建API调用的构建方式与普通更新调用类似,如以下示例所示:
PUT/attask/api/v15.0/proj?updates=[{"name":"Test_Project_1"},{"name":"Test_Project_2"}]&method=POST&apiKey=123ab-cxxxxxxxxxxxxxxxxxxxxxxxxxxxx
数据: [{
} ID: "53ff8d3d003b438b57a8a784df38f6b3",
名称:“Test_Project_1”,
对象代码:“项目”,
percentComplete: 0,
plannedCompletionDate: "2014-08-28T11:00:00:000-0400",
plannedStartDate: "2014-08-28T11:00:00:000-0400",
优先级: 0,
projectedCompletionDate: "2014-08-28T16:12:00:000-0400",
状态:“CUR”
},
{
ID: "53ff8d49003b43a2562aa34eea3b6b10",
名称:“Test_Project_2”,
对象代码:“项目”,
完成百分比: 0usi,
plannedCompletionDate: "2014-08-28T11:00:00:000-0400",
plannedStartDate: "2014-08-28T11:00:00:000-0400",
优先级: 0,
projectedCompletionDate: "2014-08-28T16:12:00:000-0400",
状态: "CUR"
}]
PUT/attask/api/v15.0/proj?Umethod=PUT&updates=[{"ID":"123abcxxxxxxxxxxxxxxxxxxxxxxxxxx","name":"Test_Project_1_ Edit"},{"ID":"123abcxxxxxxxxxxxxxxxxxxxxxxxxxx","name":"Test_Project_2_Edit"}]&apiKey=123abcxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
数据: [ {
} ID: "53ff8e15003b461d4560f7f65a440078",
名称:“Test_Project_1_Edit”,
对象代码:“项目”,
percentComplete: 0,
plannedCompletionDate: "2014-08-28T11:00:00:000-0400",
plannedStartDate: "2014-08-28T11:00:00:000-0400",
优先级: 0,
projectedCompletionDate: "2014-08-28T16:16:00:000-0400",
状态:“CUR”
},
{
ID: "53ff8e19003b46238a58d303608de502",
名称:“Test_Project_2_Edit”,
对象代码:“项目”,
percentComplete: 0,
plannedCompletionDate: "2014-08-28T11:00:00:000-0400",
plannedStartDate: "2014-08-28T11:00:00:000-0400",
优先级: 0,
projectedCompletionDate: "2014-08-28T16:16:00:000-0400",
状态: "CUR"
}]