MicrosoftDocs/azure-devops-docs

API version in TFS

pascalberger opened this issue · 6 comments

What's the correct API version(s) to use in TFS? Based on this it would be e.g. 4.0 for TFS 2018. Unfortunately there's no API documentation available for this version, as there's only API docs available for VSTS and currently only for 4.1 and 5.0.

If you look at the API documentation in 4.1 there are also different API versions for different parts of the API. Sometimes it's 4.1, sometimes 4.1-preview.
If you look at the requests TFS 2018 Update 2 web interface calls, it also uses sometimes 4.1, even though this page documents 4.0 for TFS 2018.


Document Details

Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

Good questions. We will use this issue to improve the docs around versioning. Versioning is complicated for a few reasons, including the fact that one of our goals was/is to maintain a consistent set of APIs across our cloud service (VSTS) and on-prem product (TFS). This enables partner integrations and extensions to work with both environments.

Here are a few pointers in the meantime ...

To understand which APIs are available on a particular VSTS organization (formerly called "account") or TFS project collection, our client libraries do an HTTP OPTIONS request. For example, to see the available Git REST APIs on the fabrikam-fiber-inc account using Curl:

curl -X OPTIONS https://fabrikam-fiber-inc.visualstudio.com/_apis/git -u pat:xxx

This returns an array of objects (on for each route registered in the "Git" area). Let's look at the first item in the list:

    {
      "id": "225f7195-f9c7-4d14-ab28-a83f7ff77e1f",
      "area": "git",
      "resourceName": "repositories",
      "routeTemplate": "{project}/_apis/{area}/{resource}/{repositoryId}",
      "resourceVersion": 1,
      "minVersion": "1.0",
      "maxVersion": "5.0",
      "releasedVersion": "4.1"
    }

This provides information about the project-scoped Git Repositories API. Here's what we can tell from the data:

  • This API was introduced in version 1.0 (i.e. before TFS 2015)
  • Prior to version 4.1, it was in preview, meaning callers had to append -preview to the api-version query parameter (or HTTP accept header) to call it with a POST, PATCH, DELETE, etc.
  • The resource version indicate what revision this API is on. A value of 1 indicates this API has not had any breaking changes since it was introduced and will behave the same regardless of what version you call it at. This is the case with many of our APIs because we have, in general, tried to avoid making breaking changes (i.e. changes are always additive).

Calling this API with ?api-version=1.0, ?api-version=2.0, ?api-version=4.0-preview, etc will behave the same and yield the same results in both TFS and VSTS (other than possibly some additional fields returned in later version of TFS or VSTS).

Here is another example:

    {
      "id": "a663da97-81db-4eb3-8b83-287670f63073",
      "area": "git",
      "resourceName": "recycleBinRepositories",
      "routeTemplate": "{project}/_apis/{area}/recycleBin/repositories/{repositoryId}",
      "resourceVersion": 1,
      "minVersion": "4.1",
      "maxVersion": "5.0",
      "releasedVersion": "0.0"
    }
  • This API was introduced in version 4.1, meaning it is only available in VSTS and TFS 2018 U2 and later
  • A releasedVersion of 0.0 indicates the API has not been released and is therefore still in preview. This means you should call it with ?api-version=4.1-preview. Including a resource number with the version (?api-version=4.1-preview.1) further ensure that your app/extension/tool isn't broken if this preview API evolves (i.e. a new resource version is introduced while this API is still in preview).

@willsmythe Thanks for the detailed explanation. The OPTIONS request helps a lot.

So, the following example means, that this specific endpoint is still at version 1.0 (was from TFS U2, where nearly all other endpoints are at 4.1)?

        {
            "id": "9777557b-f5a5-4a6b-94f8-39aff53b5b41",
            "area": "git",
            "resourceName": "pushes",
            "routeTemplate": "_apis/{area}/{projectId}/repositories/{repositoryId}/{resource}/{pushId}",
            "resourceVersion": 1,
            "minVersion": "1.0",
            "maxVersion": "1.0",
            "releasedVersion": "0.0"
        },

And what happens if preview is added to the call for endpoints which are no longer in preview? Will in this case the released version be called?

This particular API only exists in the "1.0" API set. It was not carried into later API sets because it has a non-standard route (the {projectId} path segment should be before /_apis).

Because we have not deprecated any older API sets, TFS 2018 U2 (for example) essentially has all existing API sets (1.0, 2.x, 3.x, 4.0, 4.1). VSTS has all of these plus 5.0 (which is currently in preview).

Re: your question about including -preview in the api-version of a call ...

First, individual APIs and entire API version sets can either be in preview or released. On a released version of TFS (on-prem), all API sets are considered released. 4.1 is the latest API set available in TFS 2018 U2 and is released. The latest API set on VSTS (currently 5.0) is always in preview, but 4.1 and earlier sets are also still available on VSTS.

For released APIs ...

  • Not specifying a version (which is only allowed on GET calls) results in the *latest released version of that API being invoked
  • With a specific version (e.g. ?api-version=3.2) results in the specified version of the API being invoked (assuming the API exists at this version)
  • With "-preview" (e.g. ?api-version=3.2-preview) is usually equivalent to not specifying -preview, but looking at the response headers can give you some clues on what's actually being invoked ...

The Content-Type header in the response tells you what version of an API was actually invoked, but keep in mind that many APIs don't actually change from one API version to another, so it's likely passing different api-version values in the requests actually results in the same API on the server being invoked (with no change in behavior or the result set between the "different" versions).

A few examples ...

Example 1: call to a released API without specifying a version

Request:

GET https://myaccount.visualstudio.com/_apis/area/resourceA

Response:

Content-Type: application/json; charset=utf-8; api-version=4.1

Analysis: although 5.0 is the latest API set available on VSTS, the set is still in preview, which means the latest released version (4.1 in this case) is invoked.

Example 2: call to a preview API without specifying a version

Request:

GET https://myaccount.visualstudio.com/_apis/area/resourceB

Response:

Content-Type: application/json; charset=utf-8; api-version=5.0-preview.1

Analysis: because this API exists in the 5.0 API set and because this set is still in preview, the 5.0-preview.1 version of the API is invoked.

Example 3: call to a released API, but with a "preview" version specified

Request:

GET https://myaccount.visualstudio.com/_apis/area/resourceA?api-version=5.0-preview

Response:

Content-Type: application/json; charset=utf-8; api-version=5.0-preview.1

Analysis: because a preview version was requested and this API exists at this version, the latest available preview version (1 in this case) is invoked.

One take-away from all of this ... always specify a specific version (e.g. "4.0", "4.1-preview.2") in your code to avoid breaks in your apps/extensions as APIs evolve.

Keep the questions coming ... this is all good stuff to work through here so we can deliver the best docs.

On a released version of TFS (on-prem), all API sets are considered released. 4.1 is the latest API set available in TFS 2018 U2 and is released.

Which means that all endpoints in TFS 2018 U2 can be called with api-version=4.1? If I check version using the OPTIONS request some endpoints are still reported as 4.1-preview, though.

My issue with this is, that we have several integrations running. Our approach until now was to define api version in an environment variable which we update after TFS update. This gives us the flexibility to change API versions. But of course we don't want to have an environment variable for each endpoint.

if I understand correctly your suggestion is to hardcode api version for each call in the code/scripts instead, and keep on this version even after TFS updates, as you won't remove API versions? An exception is if preview APIs are used code needs to be updated to the release API version once available in TFS

This conversation has been halted for a while, but wanted @willsmythe to take a look again at the last response before closing for ya @pascalberger

I'm looking to close this issue out, it's been a while since we've had any action on it. @pascalberger please let me know if you have more questions and we'll try to get it sorted.