Getting into the VersionOne Query API

Millard Ellingsworth
9 min readApr 17, 2018

If your organization requires you to use VersionOne, you’d surprise me if you didn’t have at least one story of the shape “I’d just like to know <useful bit of info> and I can’t find a way to get that out easily and repeatably, nor in a way that’s easily shared with others”. I had to visit many bits of documentation and do some experimenting and searching in order close in on an approach to solving this. This post shares my results in hopes of saving you the same pain.

One of my stories of that shape is that I’d like to have a shared Work Item Hygiene Dashboard. When I worked on and with IBM Rational Team Concert, ad hoc dashboards were super easy to make and share and every team had such a dashboard with panels for links to work items that didn’t have story points or acceptance criteria or had been in an open state for more than N days (whatever conditions concerned the team, not just the ones the vendor chose to provide). Any team member with a few spare minutes could hit the dashboard and make our world a bit better. Work item maintenance (and the improved metrics you can get from that) is everyone’s responsibility. You just have to make it easy for everyone to help — make doing the right thing easy and it’s more likely to get done (with less grumbling).

While I’m well acquainted with Collaborative Agile Lifecycle Management tools, I am not a VersionOne expert. If you have better approaches or suggestions for improvements to this one, please share in the comments (and feel free to post links to relevant material of your own). We’re all in this together. As a reader who keeps going, I’m presuming you are familiar with VersionOne, have some interest in querying it, and aren’t afraid of some technical effort and research (you’ll need to follow many of the links in this piece and read what you find there) to be successful.

meta.v1

The VersionOne (V1) product catalog has a confusing collection of options and the collection of APIs is only a bit easier to navigate. You’ll definitely need the meta.v1 endpoint as it is your source of schema/metadata information for the V1 data model. This visual depiction of the data model is also helpful [and it would be an improvement to the general API docs if it were easier to find]. A useful aspect of the meta.v1 endpoint is that you can provide the name of individual assets as part of the URL — I find it easier to have a few tabs open with just one asset’s metadata rather than scroll back and forth through the entire collection.

Unless you want a bunch of XML to sort through, be sure to use the query parameter ?xsl=api.xsl. Using only <Server Base URI>/meta.v1 will get you all assets in XML format:

V1 metadata without XSL stylesheet

<Server Base URI>/meta.v1?xsl=api.xsl gets you something for humans to read (depending on how your V1 is hosted, you may need a variation on that):

and slipping the asset type (Story in the image below) into the URL gets you just the metadata for that asset type (a much smaller document).

There is one downside to the more targeted display: the in-page anchors are mostly worthless. In the image above, I had clicked on the Member asset type related to the Owners of the Story — it didn’t go anywhere. It would be nice if it would open the Member asset type’s metadata in a new window (or at least navigate to it). In the full metadata display, this works (since there’s an anchor for each asset type). In the partial display, there is no Member section to link to (so it’s sort of information only). If you want tabs with single asset displays, you’ll need to cruft up your own URLs using the basic one and add in the asset type yourself. [It would obviously be nice if the page sensed that you had chosen an individual asset and adjusted the references appropriately.]

rest-1.v1/Data or query.v1 or …

The next question is which of those various other APIs is the one you want? For our needs, I only need to query data (no updates) and being able to do an interesting query with related assets makes the whole thing easier. From a mechanics perspective, it’s also easier to craft queries and send them “as-is” without having to convert it all into query parameters on the URL (required for the rest-1… endpoints). So that means the query.v1 endpoint is the best match for my needs. The rest-1.v1 collection of endpoints provide a more traditional RESTy approach, allowing the various HTTP verbs against the various asset types. That doesn’t make for a great test and build a query experience. [I’m told, but could not verify from the documentation nor did I experiment with this, that the rest-1 endpoints can return JSON if you send the appropriate Accept header but by default will return XML.]

API Console

We now have our basic approach and we’re armed with our metadata information. What next? While I’ll walk through using the query.v1 API for a few simple cases to demonstrate, you’ll want to spend some time with the official docs at some point. Oddly, those official docs don’t mention the API Console (you may be starting to realize why I’m writing this down). You can find the API console at <Server Base URI>/APIConsole.mvc. One upside of using the API Console is that it is browser-based and that takes care of authentication for you (so you don’t need to get an access token and deal with that complexity — which is actually worth doing for many reasons that will be explained later). But it’s a good place to start.

V1 console default — use with caution

In case you aren’t a reader of captions, yes, it says “use with caution”. Firstly, if you are reading the V1 docs on the Console (assuming you found them) they will say something like “Click the Send button to test”. When I did that, I got a “Not Found” response (which almost derailed my journey). I had some frustrating times before I found out that our organization blocks general access to “Scope/0”, so it’s not really “Not Found”, it’s just “Not Allowed”. [I realize that rest-1.v1 isn’t the API we want to use, it was just presented as the default (i.e., ought to work unless something is wrong) use case. So if you just click Send and it doesn’t work, don’t give up.]

The part of using the API Console I found frustrating (how to fix that a bit later) was that any refresh gets you that default console presentation above. Maybe it’s just me, but I’ll occasionally accidentally make a trackpad swipe that is interpreted by my browser as “Go Back to previous page.” When I swipe to go forward to get back to the API console, everything I had been working on is gone. So unless you are constantly copying your query-in-progress-of-being-written contents somewhere safe, one bad swipe and you are starting over. [I get it’s a web page and that’s how they work, which is why we’ll use it for a quick demonstration and then move on to a more robust approach.]

If you looked at the “Tour” page, you already know that query.v1 is focused on helping you query V1 and so is less of a traditional REST API and more of a V1 Query API. To use it, rather than writing GET requests, we’ll use POST requests where the details of our query are transferred in the payload (and interpreted on the server side). That payload can be in either JSON or YAML formats. At least in this context (using the API console or, later, Postman), YAML is easier to work with. [In a later post when we look at how to turn our queries into dashboard responses via a node.js service, we’ll need to convert them to JSON. I’ve had a reasonable experience using YAML to build and test via Postman and then a YAML-to-JSON converter to move the query into a JSON format.]

V1 API Console configured for query.v1 with simple query

In the image above, I’ve change the controls in the API console to use the query.v1 endpoint, changed the type of request to POST and the desired return type to JSON. Since POST enables a payload, I’ve added a simple query spec to the payload in YAML format (XML is the matching content type for the payload, there is not a YAML option).

NB: When you are testing queries, I found it useful to leave off where clauses and filter options whenever reasonable. Otherwise you can get an empty result which may lead you to incorrectly presume your query is no good. The huge downside to not filtering is the mountain of data you could get returned. I highly recommend using the “page command” to limit the size of your result set. I do this with all queries I am building and then remove it as appropriate once I’m happy.

The query itself, the YAML in the payload, is reasonably self explanatory: From the Story asset type, get the Story Name, its Status Name, its Parent ID and its Scope Name and limit the total results returned to the first (page 0) ten items. If you’ve written much SQL, you’ll quickly grok how cool that is: Status, Parent and Scope are all other objects but we didn’t have to specify any joins. Moreover, we can dip into the object’s attributes with a simple dot notation (reminiscent of using JSON objects).

I did a couple things to highlight stuff worth knowing that I’ll explain on the other side of the graphic.

V1 API Console Response

Useful things to know/notice:

  1. When you specify a simple attribute that is part of a relationship, you get a simple response, not a “relationship” object you have to pull apart. While Status is an Asset Type, by asking just for Status.Name, you get just the appropriate string. If you take the “.Name” off, you’ll get back a Status object with an ID value (_oid) that would let you retrieve that status object separately. Here I’ve requested both Status and Status.Name (the API Console makes it easy to do these sorts of experiments):
    “Status”: {
    “_oid”: “StoryStatus:809211”
    },
    “Status.Name”: “Done”
  2. Similarly, you always get back an _oid value for the target object (Story in this case). This value makes it simple to create a navigable link to the item. For a Story, you’d just take your base server URL, the story request, and append the _oid value: <Server Base URI>/story.mvc/Summary?oidToken=Story:832164
  3. This may be the most important one: If you look at the query and response, I put “Parent.ID” in the query but you see “Super.ID” in the response (that’s on purpose to make this point; I changed the request before retrieving the response): The V1 data model and whatever version of the V1 UI you use only sort of line up. In the UI version we use, there’s a menu option on a Story that says “Create Parent Portfolio Item” (a “feature” to contain the story, emphasis mine). As I was working on a query to look for Stories that did not have a Feature, I was using Parent.ID from the Story to represent that (that seemed reasonable…). But I’d follow a link I generated and the Story would (sometimes) have a Portfolio Item (feature). Digging into that, I eventually figured out that the Parent represents the Backlog Group relationship and that the owning Portfolio Item is referred to through the Super relationship. You have been warned.

Have fun with this! You now have the knowledge necessary to drag just about any data you want from your V1 repository. Since this post has gotten rather long, I’ll cover moving this to Postman (and why you should) in my next post.

As I alluded to earlier, the docs aren’t super helpful. To really dig into this, you’ll need to experiment, study the metadata more than once, and review additional examples, like the collection of sample queries. [Beware, not all of these are for the query.v1 API, so look for ones that have some YAML code in them.] There are some interesting relationships available on items, like Parent and up that will retrieve the entire collection of superordinate items. Just remember that you likely really want Super and up.

Continued in Working with the VersionOne API.

Thanks to my friend Matt Poletiek for his technical contributions and review.

--

--

Millard Ellingsworth

Scrum Master, DevOps+Agile Coach, Developer, handyman and occasional musician. All content represents my own opinions. #Agile #DevOps