Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Azure DevOps Services | Azure DevOps Server | Azure DevOps Server 2022
Cet article fournit des exemples pratiques d’API REST pour Azure DevOps Services. Ces exemples illustrent des opérations courantes telles que la récupération de projets, la gestion des éléments de travail et l’utilisation de modèles d’authentification sécurisés avec l’ID Microsoft Entra.
Importante
Ces exemples utilisent l’authentification d’ID Microsoft Entra, qui est l’approche recommandée pour les applications de production. Bien que les jetons d’accès personnels (PAT) puissent être utilisés pour des scripts simples, Microsoft Entra ID offre de meilleures fonctionnalités de sécurité et de gouvernance.
Vue d’ensemble de l’authentification
Les API REST Azure DevOps prennent en charge plusieurs méthodes d’authentification :
- ID Microsoft Entra - Recommandé pour les applications de production (utilisés dans ces exemples)
- Jetons d’accès personnels (PAT) - Authentification simple pour les scripts et les tests
- OAuth 2.0 - Pour les applications tierces
- Principaux de service - Pour les scénarios automatisés
Importante
Nous recommandons d'utiliser les jetons Microsoft Entra, plus sécurisés, plutôt que les jetons d’accès personnels, qui présentent un risque plus élevé. Apprenez-en davantage sur nos efforts de réduction de l’utilisation du PAT. Passez en revue nos conseils d’authentification pour choisir le mécanisme d’authentification approprié pour vos besoins.
Authentification par Microsoft Entra ID
Pour l'authentification via Microsoft Entra ID, vous devez enregistrer une application et obtenir un jeton d'accès. Voici comment s’authentifier à l’aide de la bibliothèque d’authentification Microsoft (MSAL) :
Tout d’abord, installez le package NuGet requis :
<PackageReference Include="Microsoft.Identity.Client" Version="4.61.3" />
using Microsoft.Identity.Client;
using System.Net.Http.Headers;
public async Task<string> GetAccessTokenAsync()
{
var app = PublicClientApplicationBuilder
.Create("{your-client-id}")
.WithAuthority("https://login.microsoftonline.com/{your-tenant-id}")
.WithRedirectUri("http://localhost")
.Build();
var scopes = new[] { "https://app.vssps.visualstudio.com/.default" };
try
{
var result = await app.AcquireTokenInteractive(scopes).ExecuteAsync();
return result.AccessToken;
}
catch (MsalException ex)
{
Console.WriteLine($"Authentication failed: {ex.Message}");
throw;
}
}
Exemples d’API REST
Répertorier les projets (GET)
Récupérez tous les projets de votre organisation :
Exemple en code C#
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using Microsoft.Identity.Client;
public async Task<string> GetProjectsAsync(string organization)
{
using var client = new HttpClient();
// Get Microsoft Entra ID access token
var entraIdAccessToken = await GetAccessTokenAsync();
// Set base address and headers
client.BaseAddress = new Uri($"https://dev.azure.com/{organization}/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// Add authentication header
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", entraIdAccessToken);
try
{
var response = await client.GetAsync("_apis/projects?api-version=7.2");
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
catch (HttpRequestException ex)
{
Console.WriteLine($"Request failed: {ex.Message}");
throw;
}
}
Exemple PowerShell
# Install required module if not already installed
# Install-Module -Name MSAL.PS -Force
Import-Module MSAL.PS
$clientId = "your-client-id"
$tenantId = "your-tenant-id"
$organization = "your-organization"
# Get access token
$token = Get-MsalToken -ClientId $clientId -TenantId $tenantId -Scopes "https://app.vssps.visualstudio.com/.default"
$headers = @{
'Authorization' = "Bearer $($token.AccessToken)"
'Accept' = 'application/json'
}
$uri = "https://dev.azure.com/$organization/_apis/projects?api-version=7.2"
try {
$response = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers
Write-Host "Retrieved $($response.count) projects"
$response.value | ForEach-Object { Write-Host "- $($_.name)" }
}
catch {
Write-Error "Failed to retrieve projects: $($_.Exception.Message)"
}
Créer un élément de travail (POST)
Créez un élément de travail dans votre projet :
Exemple en code C#
using System.Text;
using Newtonsoft.Json;
public async Task<string> CreateWorkItemAsync(string organization, string project)
{
using var client = new HttpClient();
// Get Microsoft Entra ID access token
var entraIdAccessToken = await GetAccessTokenAsync();
// Set base address and headers
client.BaseAddress = new Uri($"https://dev.azure.com/{organization}/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", entraIdAccessToken);
var workItem = new
{
fields = new
{
SystemTitle = "Sample work item",
SystemDescription = "Created via REST API with Microsoft Entra ID",
SystemTags = "api; sample; entra-id"
}
};
var json = JsonConvert.SerializeObject(workItem);
var content = new StringContent(json, Encoding.UTF8, "application/json");
try
{
var response = await client.PostAsync($"{project}/_apis/wit/workitems/$Task?api-version=7.2", content);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
catch (HttpRequestException ex)
{
Console.WriteLine($"Request failed: {ex.Message}");
throw;
}
}
Exemple PowerShell
Import-Module MSAL.PS
$clientId = "your-client-id"
$tenantId = "your-tenant-id"
$organization = "your-organization"
$project = "your-project"
# Get access token
$token = Get-MsalToken -ClientId $clientId -TenantId $tenantId -Scopes "https://app.vssps.visualstudio.com/.default"
$headers = @{
'Authorization' = "Bearer $($token.AccessToken)"
'Content-Type' = 'application/json'
}
$body = @{
fields = @{
'System.Title' = 'Sample work item'
'System.Description' = 'Created via REST API with Microsoft Entra ID'
'System.Tags' = 'api; sample; entra-id'
}
} | ConvertTo-Json
$uri = "https://dev.azure.com/$organization/$project/_apis/wit/workitems/`$Task?api-version=7.2"
try {
$response = Invoke-RestMethod -Uri $uri -Method Post -Headers $headers -Body $body
Write-Host "Work item created with ID: $($response.id)"
}
catch {
Write-Error "Failed to create work item: $($_.Exception.Message)"
}
Mettre à jour l’élément de travail (PATCH)
Mettez à jour l’état d’un élément de travail existant :
Exemple en code C#
using System.Text;
using Newtonsoft.Json;
public async Task<string> UpdateWorkItemAsync(string organization, string project, int workItemId)
{
using var client = new HttpClient();
// Get Microsoft Entra ID access token
var entraIdAccessToken = await GetAccessTokenAsync();
// Set base address and headers
client.BaseAddress = new Uri($"https://dev.azure.com/{organization}/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", entraIdAccessToken);
var patchOperations = new[]
{
new
{
op = "add",
path = "/fields/System.State",
value = "In Progress"
},
new
{
op = "add",
path = "/fields/System.AssignedTo",
value = "user@example.com"
}
};
var json = JsonConvert.SerializeObject(patchOperations);
var content = new StringContent(json, Encoding.UTF8, "application/json-patch+json");
try
{
var response = await client.PatchAsync($"{project}/_apis/wit/workitems/{workItemId}?api-version=7.2", content);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
catch (HttpRequestException ex)
{
Console.WriteLine($"Request failed: {ex.Message}");
throw;
}
}
Exemple PowerShell
Import-Module MSAL.PS
$clientId = "your-client-id"
$tenantId = "your-tenant-id"
$organization = "your-organization"
$project = "your-project"
$workItemId = 123 # Replace with actual work item ID
# Get access token
$token = Get-MsalToken -ClientId $clientId -TenantId $tenantId -Scopes "https://app.vssps.visualstudio.com/.default"
$headers = @{
'Authorization' = "Bearer $($token.AccessToken)"
'Content-Type' = 'application/json-patch+json'
}
$body = @(
@{
op = "add"
path = "/fields/System.State"
value = "In Progress"
},
@{
op = "add"
path = "/fields/System.AssignedTo"
value = "user@example.com"
}
) | ConvertTo-Json
$uri = "https://dev.azure.com/$organization/$project/_apis/wit/workitems/$workItemId?api-version=7.2"
try {
$response = Invoke-RestMethod -Uri $uri -Method Patch -Headers $headers -Body $body
Write-Host "Work item $workItemId updated successfully"
}
catch {
Write-Error "Failed to update work item: $($_.Exception.Message)"
}
Supprimer un élément de travail (DELETE)
Supprimez un élément de travail de votre projet :
Exemple en code C#
public async Task<bool> DeleteWorkItemAsync(string organization, string project, int workItemId)
{
using var client = new HttpClient();
// Get Microsoft Entra ID access token
var entraIdAccessToken = await GetAccessTokenAsync();
// Set base address and headers
client.BaseAddress = new Uri($"https://dev.azure.com/{organization}/");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", entraIdAccessToken);
try
{
var response = await client.DeleteAsync($"{project}/_apis/wit/workitems/{workItemId}?api-version=7.2");
response.EnsureSuccessStatusCode();
Console.WriteLine($"Work item {workItemId} deleted successfully");
return true;
}
catch (HttpRequestException ex)
{
Console.WriteLine($"Request failed: {ex.Message}");
throw;
}
}
Bibliothèques .NET pour client
Pour les applications .NET, utilisez les bibliothèques clientes .NET Azure DevOps pour améliorer la sécurité des types et faciliter le développement.
Installation
Ajoutez ces packages NuGet à votre projet :
<PackageReference Include="Microsoft.TeamFoundationServer.Client" Version="19.225.1" />
<PackageReference Include="Microsoft.VisualStudio.Services.Client" Version="19.225.1" />
<PackageReference Include="Microsoft.Identity.Client" Version="4.61.3" />
Obtenir des projets à l’aide du client .NET
using Microsoft.TeamFoundation.Core.WebApi;
using Microsoft.VisualStudio.Services.Common;
using Microsoft.VisualStudio.Services.WebApi;
using Microsoft.Identity.Client;
public async Task<IEnumerable<TeamProjectReference>> GetProjectsAsync(string organizationUrl)
{
var uri = new Uri(organizationUrl);
// Get Microsoft Entra ID access token
var entraIdAccessToken = await GetAccessTokenAsync();
var credentials = new VssOAuthAccessTokenCredential(entraIdAccessToken);
using var connection = new VssConnection(uri, credentials);
using var projectClient = connection.GetClient<ProjectHttpClient>();
try
{
var projects = await projectClient.GetProjects();
return projects;
}
catch (Exception ex)
{
Console.WriteLine($"Error retrieving projects: {ex.Message}");
throw;
}
}
Créer un élément de travail à l’aide du client .NET
using Microsoft.TeamFoundation.WorkItemTracking.WebApi;
using Microsoft.TeamFoundation.WorkItemTracking.WebApi.Models;
using Microsoft.VisualStudio.Services.WebApi.Patch;
using Microsoft.VisualStudio.Services.WebApi.Patch.Json;
using Microsoft.Identity.Client;
public async Task<WorkItem> CreateWorkItemAsync(string organizationUrl, string project)
{
var uri = new Uri(organizationUrl);
// Get Microsoft Entra ID access token
var entraIdAccessToken = await GetAccessTokenAsync();
var credentials = new VssOAuthAccessTokenCredential(entraIdAccessToken);
using var connection = new VssConnection(uri, credentials);
using var witClient = connection.GetClient<WorkItemTrackingHttpClient>();
var patchDocument = new JsonPatchDocument
{
new JsonPatchOperation
{
Operation = Operation.Add,
Path = "/fields/System.Title",
Value = "Sample work item created via .NET client with Microsoft Entra ID"
},
new JsonPatchOperation
{
Operation = Operation.Add,
Path = "/fields/System.Description",
Value = "This work item was created using the Azure DevOps .NET client library with Microsoft Entra ID authentication"
}
};
try
{
var workItem = await witClient.CreateWorkItemAsync(patchDocument, project, "Task");
return workItem;
}
catch (Exception ex)
{
Console.WriteLine($"Error creating work item: {ex.Message}");
throw;
}
}
Gestion des erreurs
Implémentez toujours une gestion des erreurs appropriée dans vos applications :
try
{
var response = await client.GetAsync(requestUri);
response.EnsureSuccessStatusCode();
var content = await response.Content.ReadAsStringAsync();
// Process successful response
}
catch (HttpRequestException ex)
{
// Handle HTTP-related errors
Console.WriteLine($"HTTP Error: {ex.Message}");
}
catch (TaskCanceledException ex) when (ex.InnerException is TimeoutException)
{
// Handle timeout
Console.WriteLine("Request timed out");
}
catch (Exception ex)
{
// Handle other errors
Console.WriteLine($"Unexpected error: {ex.Message}");
}
Meilleures pratiques
- Utiliser l’ID Microsoft Entra : Utiliser l’authentification d’ID Microsoft Entra sur des PAT pour les applications de production
- Utiliser HTTPS : Toujours utiliser des connexions sécurisées pour les appels d’API
- Gérer les limites de débit : Implémenter une logique de réessayer avec un recul exponentiel
- Réponses du cache : Stocker les données fréquemment sollicitées pour réduire les appels d’API
- Utilisez des versions spécifiques de l’API : fixez des versions spécifiques pour éviter les changements cassants.
- Valider les entrées : toujours valider les entrées utilisateur avant d’effectuer des appels d’API
- Journaliser correctement : Enregistrer les interactions de l'API pour le débogage, mais ne jamais enregistrer les identifiants.
- Gestion des jetons : implémenter une mise en cache et une logique d’actualisation de jetons appropriés pour les jetons d’ID Microsoft Entra