Visual Studio Online Extensibility – REST API

Visual Studio Online IntegrateAm 28. Oktober 2014 hat Microsoft ein neues API veröffentlicht, das Daten aus Visual Studio Online zur Verfügung stellt. Benutzt werden hierzu Standard-Web-Technologien wie REST, JSON und OAuth. Dieses API kann als zukünftige Basis-Schnittstelle für Visual Studio Online und Team Foundation Server angesehen werden. Ulrike Stirnweiß und ich haben bereits mit Christian Binder, Senior Evangelist von Microsoft, über die neuen Möglichkeiten gesprochen. Ein Video des Talks könnt Ihr Euch hier ansehen. Zusammen mit Ulli werde ich in einer Artikel-Serie weiterführende Informationen zu diesem API geben. Los geht’s mit dem REST-Service – die REST API.

Natürlich gibt es das REST API schon ein paar Monate länger (Preview seit Mai 2014) und somit konnten Ulli und ich uns schon eine Weile damit beschäftigen. Zusammen mit Marco Richardson haben wir eine Windows App entwickelt, die ihre Daten über die neue Schnittstelle von Visual Studio Online bezieht.RestApi_VSO_Evolution

Abbildung 1: Screenshots aus dem TFS Showcase

Ich werde Euch in diesem Beitrag die Grundlagen der REST API an Hand einer einfachen Konsolenanwendung näher bringen, während Euch Ulli in einem weiteren Beitrag nützliche Tipps und Tricks zur Verwendung der API in einer Windows App liefert.

REST API

Zuerst möchte ich die Frage klären, was man eigentlich unter einer REST API versteht. Der Begriff REST steht für REpresentational State Transfer und API für Application Programming Interface. Demzufolge ist eine REST API also eine Art Beschreibung für eine Schnittstelle einer Web-Anwendung. Ein sog. RESTful Service zeichnet sich unteranderem durch folgende Merkmale aus:

  • er referenziert alle Datenobjekte durch eine eindeutige URL
  • er verwendet die Standard-Methoden des http-Protokolls (GET, PUT, POST und DELETE)
  • er kann angefragte Objekte unter anderem als JSON serialisiert zurückgeben.

Diese drei Eigenschaften machen die REST API von Visual Studio Online relativ leicht benutzbar und ermöglichen einen verständlichen Aufbau. Die URLs folgen dabei folgendem Pattern:

https://{account}.VisualStudio.com/DefaultCollection/_apis[/{area}]/{resource}?api-version=1.0

Der Platzhalter {account} steht für den tatsächlichen Visual Studio Account, in meinem Fall  https://almsports.visualstudio.com. Mit {area} werden dann die tatsächlichen Bereiche von Visual Studio Online referenziert und {resource} beschreibt das Datenobjekt, welches abgefragt werden soll.

Team Projekte

Um z. B. Informationen aus einem Projekte abzurufen, muss folgender Aufruf abgesetzt werden:

https://almsports.visualstudio.com/DefaultCollection/_apis/projects/f2c5c767-36ba-485a-b478-f6de0f8f84b3?api-version=1.0

um das folgende JSON-Objekt als Rückgabewert zu bekommen:

{
 
"id": "f2c5c767-36ba-485a-b478-f6de0f8f84b3",
 
"name": "gitStart",
 
"url": "https://almsports.visualstudio.com/DefaultCollection/_apis/projects/f2c5c767-36ba-485a-b478-f6de0f8f84b3",
 
"description": "Git",
 
"state": "wellFormed",
 
"_links": {
 
   "self": {
 
      "href": "https://almsports.visualstudio.com/DefaultCollection/_apis/projects/f2c5c767-36ba-485a-b478-f6de0f8f84b3"
 
   },
 
   "collection": {
 
      "href": "https://almsports.visualstudio.com/_apis/projectCollections/31360acb-beb3-4404-bfa2-c1d02c0be2d5"
 
   },
 
   "web": {
 
      "href": "https://almsports.visualstudio.com/DefaultCollection/gitStart"
 
   }
 
},
 
"defaultTeam": {
 
   "id": "0c655975-4f18-4a4a-bb28-527cf4e44489",
 
   "name": "gitStart Team",
 
   "url": "https://almsports.visualstudio.com/DefaultCollection/_apis/projects/f2c5c767-36ba-485a-b478-f6de0f8f84b3/teams/0c655975-4f18-4a4a-bb28-527cf4e44489"
 
   }
 
}

Hinweis: Ein sehr nützliches Tool im Umgang mit der VSO REST API oder allgemein mit RESTful Services ist das Browser-Tool POSTMAN, das für den Chrome-Browser als kostenloses Plug-in zur Verfügung steht.

Der Aufbau der Rückgabe-Objekte erfolgt nahezu immer dem gleichen Schema. Das JSON-Objekt enthält die Basis-Daten eines Team-Projektes aus meinem VSO-Account „almsports“ und hält im Property name den Wert „gitStart“. Wie jedes Objekt ist es über eine id eindeutig identifizierbar und beinhaltet in der Property url den kompletten Aufruf für die Ressource. Innerhalb des Datensatzes des Team Projekts wird ein weiteres Objekt mitgeliefert, welches durch das Property defaultTeam beschrieben wird. Es enthält ebenso eine eindeutige id, einen name und eine url.

In einer .NET Konsolen Applikation kann man relativ einfach die Daten eines Visual Studio Online Accounts abrufen und ausgeben. Dafür genügen wenige Zeilen Code.

Als erstes wird ein HttpClient mit Hilfe eines using Statements erzeugt, um http-Requests absetzen und http-Responses empfangen zu können. Da die REST API von Visual Studio Online bekanntermaßen JSON-Objekte zurückliefert, muss der Accept Header des Aufrufs mit „application/json“ gesetzt werden.

using (HttpClient client = new HttpClient())
{
   //set default RequestHeader
   client.DefaultRequestHeaders.Accept.Add(new 
      System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
 
   //Set alternate credentials
   client.DefaultRequestHeaders.Authorization = 
      new AuthenticationHeaderValue("Basic", Convert.ToBase64String( 
         System.Text.ASCIIEncoding.ASCII.GetBytes(                 
            string.Format("{0}:{1}", _altUsername, _altPassword))));
 
   //do something
}

Die Authentifizierung im obigen Beispiel findet mit den Alternativen Credentials eines VSO-Benutzers statt, dabei wird der AuthenticationHeader auf „Basic“ gesetzt. Aber Achtung: Diese Art der Authentifizierung ist definitiv nicht für den produktiven Einsatz gedacht, da bei jedem http-Aufruf Username und Passwort übertragen werden müssen. Eine bessere Art der Authentifizierung, nämlich OAuth 2.0 für VSO, werde ich einem weiteren Blog-Post vorstellen.

Hinweis: Ein Sample zu den vorgestellten Code-Beispielen steht auf GitHub bereit und kann verwendet werden. Ihr müsst lediglich Euren Account-Namen eintragen und schon könnt Ihr loslegen.

Work Items abrufen

Ein relativ großer Bereich der REST API in Visual Studio Online ist das Work Item Tracking. Mit Hilfe des REST Interface kann auf nahezu alle Bereiche des Work Item Tracking zugegriffen werden. Work Items können erstellt oder editiert, Attachements und Historie können ausgelesen und Tags können vergeben werden.

RestAPI_WorkItems

Abbildung 2: Übersicht der unterstützten Work Item Bereiche der REST API

Work Item-Informationen können über zwei verschiedene Wege abgerufen werden: Entweder man verwendet eine vordefinierte Abfrage (Query) aus einem Team-Projekt, oder man erstellt sich eine eigene Abfrage mit Hilfe der Work Item Query Language (WIQL). Egal welche Methode letztendlich gewählt wird, beide Abfrage-Typen liefern erst nur eine Liste von Work Item IDs zurück. Um detaillierte Work Item Informationen zu erhalten, muss eine zweite Abfrage abgesetzt werden, in der eine der Work Item IDs als zusätzlicher Identifier verwendet werden muss.

string baseUrl = String.Format(constBaseUrl, projectName + "/");
 
//create Json Object with work item query
JObject wiql = JObject.FromObject(new
{
   query = string.Format("SELECT [System.Id], [System.WorkItemType], [System.Title], [System.AssignedTo], [System.State], [System.Tags] " +
   "FROM WorkItemLinks " +
   "Where Source.[System.WorkItemType] IN GROUP 'Microsoft.RequirementCategory' " +
   "AND Target.[System.WorkItemType] IN GROUP 'Microsoft.RequirementCategory' " +
   "AND Target.[System.State] IN ('New','Approved','Committed') " +
   "AND [System.Links.LinkType] = 'System.LinkTypes.Hierarchy-Forward' " +
   "ORDER BY [Microsoft.VSTS.Common.BacklogPriority] ASC, " +
   "[System.Id] ASC MODE (Recursive, ReturnMatchingChildren)")
});
 
//first we only get all work item ids
var responseBody = await Common.PushAsync(client, wiql, 
   String.Format(baseUrl + "/wit/wiql?{0}", constApiVersion));

Anschließend werden in einer zweiten Query, in der die zurückgegeben Work Item IDs zusammen mit einem Where-Statement stehen, die Detailinformationen der Work Items
angefragt. Dabei muss unbedingt darauf geachtet werden, dass kein Projektname in der URL angegeben wird, sonst wird die angefragte Ressource vom Service nicht gefunden und man bekommt eine „404 not found“ Fehlermeldung zurück.

//this time base URL is without projectname!!!
baseUrl = String.Format(constBaseUrl, "");
 
//set fields - which data we want to get
string whereClause =
   string.Format("fields=System.Id,System.Title,System.WorkItemType,Microsoft.VSTS.Scheduling.RemainingWork");
 
//create uri for requesting work item data
string uriString = String.Format(baseUrl + "wit/workitems?ids={0}", workItemStrings), whereClause);

Das JSON der Rückgabe sollte dann wie folgt aussehen und kann z.B. im JSON Visualizer, einem Visualizer des Debugging-Watch-Window von  Visual Studio 2013, überprüft werden.

RestApi_JSON_Response

Abbildung 3: JSON Response der Work Item Query

Ulli Stirnweiss wird in Kürze auf Ihrem Blog einen Artikel posten, in dem sie Euch erklärt, wie man aus einer Windows App heraus Visual Studio Online Daten ausliest.

Stay tuned.

[1] http://almsports.net/visual-studio-integrate-rest-api-oauth-service-hooks/1449/#more-1449

[2] http://www.visualstudio.com/en-us/integrate/get-started/get-started-rest-basics-vsi

[3] https://github.com/almsports/VSORestSample