These are evolving notes demonstrating a new Bulk API for VersionOne Lifecycle to support Create, Update, and Execute Operation commands built upon the powerful and intuitive query.v1 syntax.
This functionality exists in 18.0
releases at http://host/instance/api/asset
. It's in production and in usage by customers today. See the Customer requests section about tickets and requests customers have been making for years for features like this.
Please post feedback in #lifecycle-bulk-api in Slack.
Below are a couple cURL examples for Create scenarios with either JSON or YAML.
See the Features and End to End Functional Tests section for more Create scenarios plus Update and Execute Operation scenario tests.
curl -i -X POST \
-H "Content-Type:application/json" \
-H "Authorization:Bearer 1.BO9wxGpDbI2Oh2OPbhb7wW4ghj0=" \
-d \
'{
"Scope": "System (All Projects)",
"AssetType": "Story",
"Name": "Story"
}' \
'https://www4.v1host.com/VersionOneJG/api/asset'
When using JSON, you just group your multiple Assets into an array:
curl -i -X POST \
-H "Content-Type:application/json" \
-H "Authorization:Bearer 1.BO9wxGpDbI2Oh2OPbhb7wW4ghj0=" \
-d \
'[
{
"Scope": "System (All Projects)",
"AssetType": "Story",
"Name": "Story-1",
"Children": [
{
"AssetType": "Test",
"Name": "Test-1 in Story-1"
},
{
"AssetType": "Task",
"Name": "Task-1 in Story-1"
},
{
"AssetType": "Test",
"Name": "Test-2 in Story-1"
},
{
"AssetType": "Task",
"Name": "Task-2 in Story-1"
}
]
},
{
"Scope": "System (All Projects)",
"AssetType": "Story",
"Name": "Story-2",
"Children": [
{
"AssetType": "Test",
"Name": "Test-1 in Story-2"
},
{
"AssetType": "Task",
"Name": "Task-1 in Story-2"
},
{
"AssetType": "Test",
"Name": "Test-2 in Story-2"
},
{
"AssetType": "Task",
"Name": "Task-2 in Story-2"
}
]
},
{
"Scope": "System (All Projects)",
"AssetType": "Story",
"Name": "Story-3",
"Children": [
{
"AssetType": "Test",
"Name": "Test-1 in Story-3"
},
{
"AssetType": "Task",
"Name": "Task-1 in Story-3"
},
{
"AssetType": "Test",
"Name": "Test-2 in Story-3"
},
{
"AssetType": "Task",
"Name": "Task-2 in Story-3"
}
]
}
]' \
'https://www4.v1host.com/VersionOneJG/api/asset'
curl -i -X POST \
-H "Content-Type:text/yaml" \
-H "Authorization:Bearer 1.BO9wxGpDbI2Oh2OPbhb7wW4ghj0=" \
-d \
'Scope: System (All Projects)
AssetType: Story
Name: Story' \
'https://www4.v1host.com/VersionOneJG/api/asset'
When using YAML, you use the ---
document separator character to specify multiple Assets.
curl -i -X POST \
-H "Content-Type:text/yaml" \
-H "Authorization:Bearer 1.BO9wxGpDbI2Oh2OPbhb7wW4ghj0=" \
-d \
'Scope: System (All Projects)
AssetType: Story
Name: Story-1
Children:
- AssetType: Test
Name: Test-1 in Story-1
- AssetType: Task
Name: Task-1 in Story-1
- AssetType: Test
Name: Test-2 in Story-1
- AssetType: Task
Name: Task-2 in Story-1
---
Scope: System (All Projects)
AssetType: Story
Name: Story-2
Children:
- AssetType: Test
Name: Test-1 in Story-2
- AssetType: Task
Name: Task-1 in Story-2
- AssetType: Test
Name: Test-2 in Story-2
- AssetType: Task
Name: Task-2 in Story-2
---
Scope: System (All Projects)
AssetType: Story
Name: Story-3
Children:
- AssetType: Test
Name: Test-1 in Story-3
- AssetType: Task
Name: Task-1 in Story-3
- AssetType: Test
Name: Test-2 in Story-3
- AssetType: Task
Name: Task-2 in Story-3' \
'https://www4.v1host.com/VersionOneJG/api/asset'
Whether sending YAML or JSON, the result will always be in JSON, and includes a variety of information about the processing and includes a list and count of how many Assets were created, modified, or operated on. Note that if you send a payload that is nothing but a standard query.v1
payload it will just return a query result for you.
{
"requestId": "9c5ac358-da24-4cf5-b2b8-c88ee902a293",
"createdDate": "2018-02-02T20:49:54.5776014Z",
"completedDate": "2018-02-02T20:49:54.7336065Z",
"duration": "00:00:00.1560051",
"durationSeconds": 0.15600509999999998,
"complete": true,
"processing": false,
"assetsCreated": {
"oidTokens": [
"Story:251186",
"Test:251187",
"Task:251188",
"Test:251189",
"Task:251190",
"Story:251191",
"Test:251192",
"Task:251193",
"Test:251194",
"Task:251195",
"Story:251196",
"Test:251197",
"Task:251198",
"Test:251199",
"Task:251200"
],
"count": 15
},
"assetsModified": {
"oidTokens": [],
"count": 0
},
"assetsOperatedOn": {
"oidTokens": [],
"count": 0
},
"queryResult": {
"results": [],
"count": -1
}
}
The basic Create, Update, and Execute features have a number of tests that demonstrate and verify their functionality. The tests are located here.
- Create single Story with Scope referenced by OID Token
- Create single Story with Scope referenced by Name
- Create two Stories with Scope referenced by Name and OID Token
- Create single Story that has two Children, of type Task and Test
- Create Scope, Epic, and Story via Subs relation
- Update Owners relational Attribute on two Stories, adding two new owners by OID Token
- Update Owners relational Attribute on single Story, removing one of two owners by OID Token
- Update Owners relational Attribute on single Story, adding two new owners by OID Token
- Update Owners relational Attribute on single Story, adding and removing owners with object context pointing to scalars by OID Token
- Update Owners relational Attribute on single Story, adding and removing owners with object context pointing to arrays by OID Token
- Update Owners relational Attribute on single Story, adding a new owner by OID Token
- Update Name Text scalar Attribute on two Stories, replacing one exact match string with another by OID Token
- Update Name LongText scalar Attribute on two Stories, replacing one exact match string with another by OID Token
- Update Epic, changing its Subs relation by removing Story references
- Update Epic, changing its Subs relation by adding Story references via subquery
- Update Epic, changing its Subs relation by adding Story references via subquery
- Update Epic, changing its Name and Subs relation, referencing an existing Story and adding a new one
- Update Description LongText scalar Attribute on two Defects, replacing one exact match string with another by OID Token
- Update Description scalar Attribute on two Stories matching a where clause by Scope OID Token
- Execute Delete Operation upon two Stories matching a where clause by Scope OID Token
You can run the functional tests by cloning the [versionone/automation] repo and then doing the following:
cd automation
npm install
LIFECYCLE_URL=http://yourhost/instance npm test -- lifecycle/feature_tests/asset_api
For an even deeper technical explanation, see this gist: https://gist.github.com/JogoShugh/92243c8f5759c5de19859c4ed1c1f92e. Long term, the goal is to support long-running "Jobs" that can recover from downtime and pick up where they left off.
As an example of an integration that utilizes this endpoint support, see this code:
The following lines (from the link above) of ECMAScript produce the large payload in the 02 Create Deep Graph of Assets.yaml
or 02 Create Deep Graph of Assets.json
files of this gist (these enhancements will, like query.v1, support input as either YAML or JSON). You can see how this eases sending data into VersionOne from objects in memory of a script or program. Most importantly, this builds up a nested set of Assets so that you don't have to fire off dozens of HTTP requests. You just send ONE REQUEST!
const lessonToAssetApiPayload = (lesson, scopeName) => {
const epic = {
AssetType: 'Epic',
Scope: scopeName,
Description: lesson.description,
Name: lesson.title,
Subs: []
};
for(const section of lesson.sections) {
const story = {
AssetType: 'Story',
Name: section.title,
Description: section.description,
Children: []
};
for(const part of section.parts) {
const task = {
AssetType: 'Task',
Name: part.title
};
story.Children.push(task);
}
epic.Subs.push(story);
}
return epic;
};
Each of these tickets express a desire for these kinds of features:
https://versiononesupport.zendesk.com/agent/tickets/20919
https://versiononesupport.zendesk.com/agent/tickets/4559
https://versiononesupport.zendesk.com/agent/tickets/24156
https://versiononesupport.zendesk.com/agent/tickets/11352
https://versiononesupport.zendesk.com/agent/tickets/2502
https://versiononesupport.zendesk.com/agent/tickets/26001
https://versiononesupport.zendesk.com/agent/tickets/782
https://versiononesupport.zendesk.com/agent/tickets/7574
https://versiononesupport.zendesk.com/agent/tickets/19010
https://versiononesupport.zendesk.com/agent/tickets/3566
https://versiononesupport.zendesk.com/agent/tickets/1570