Partilhar via


Exemplos de REST API para Azure DevOps

Azure DevOps Serviços | Azure DevOps Server | Azure DevOps Server 2022

Este artigo fornece exemplos práticos de APIs REST para Azure DevOps Services. Estes exemplos demonstram operações comuns como recuperar projetos, gerir itens de trabalho e utilizar padrões de autenticação segura com o Microsoft Entra ID.

Importante

Considere usar tokens mais seguros Microsoft Entra em vez de tokens de acesso pessoal de maior risco. Para mais informações, consulte Reduzir o uso do PAT. Consulte as orientações de autenticação para escolher o mecanismo de autenticação adequado às suas necessidades.

Descrição geral da autenticação

As APIs REST do Azure DevOps suportam vários métodos de autenticação:

  • Microsoft Entra ID - Recomendado para aplicações de produção (usados nestas amostras)
  • Personal Access Tokens (PATs) - Autenticação simples para scripts e testes
  • Principais de serviço e identidades geridas - Para cenários automatizados

Sugestão

Pode usar IA para ajudar nesta tarefa mais adiante neste artigo, ou consultar Enable AI assistance with Azure DevOps MCP Server para começar.

Autenticação do Microsoft Entra ID

Para a autenticação do Microsoft Entra ID, regista uma aplicação e obtém um token de acesso. Aqui está como autenticar usando a Microsoft Authentication Library (MSAL):

Primeiro, instale o pacote NuGet necessário:

<PackageReference Include="Microsoft.Identity.Client" Version="4.67.2" />
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;
    }
}

Exemplos de API REST

Listar projetos (GET)

Recupere todos os projetos em sua organização:

Exemplo de 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;
    }
}

Exemplo do PowerShell

# Install the Az.Accounts module if not already installed
# Install-Module -Name Az.Accounts -Force

# Sign in (interactive prompt) or use Connect-AzAccount -Identity for managed identity
Connect-AzAccount -TenantId "your-tenant-id"

$organization = "your-organization"

# Get access token for Azure DevOps
$token = Get-AzAccessToken -ResourceUrl "https://app.vssps.visualstudio.com/"

$headers = @{
    'Authorization' = "Bearer $($token.Token)"
    '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)"
}

Criar item de trabalho (POST)

Crie um novo item de trabalho em seu projeto:

Exemplo de 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 patchOperations = new[]
    {
        new { op = "add", path = "/fields/System.Title", value = "Sample work item" },
        new { op = "add", path = "/fields/System.Description", value = "Created via REST API with Microsoft Entra ID" },
        new { op = "add", path = "/fields/System.Tags", value = "api; sample; entra-id" }
    };
    
    var json = JsonConvert.SerializeObject(patchOperations);
    var content = new StringContent(json, Encoding.UTF8, "application/json-patch+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;
    }
}

Exemplo do PowerShell

# Sign in (interactive prompt) or use Connect-AzAccount -Identity for managed identity
Connect-AzAccount -TenantId "your-tenant-id"

$organization = "your-organization"
$project = "your-project"

# Get access token for Azure DevOps
$token = Get-AzAccessToken -ResourceUrl "https://app.vssps.visualstudio.com/"

$headers = @{
    'Authorization' = "Bearer $($token.Token)"
    'Content-Type' = 'application/json-patch+json'
}

$body = @(
    @{
        op = "add"
        path = "/fields/System.Title"
        value = "Sample work item"
    },
    @{
        op = "add"
        path = "/fields/System.Description"
        value = "Created via REST API with Microsoft Entra ID"
    },
    @{
        op = "add"
        path = "/fields/System.Tags"
        value = "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)"
}

Atualizar item de trabalho (PATCH)

Atualizar o estado de um item de trabalho existente:

Exemplo de 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;
    }
}

Exemplo do PowerShell

# Sign in (interactive prompt) or use Connect-AzAccount -Identity for managed identity
Connect-AzAccount -TenantId "your-tenant-id"

$organization = "your-organization"
$project = "your-project"
$workItemId = 123  # Replace with actual work item ID

# Get access token for Azure DevOps
$token = Get-AzAccessToken -ResourceUrl "https://app.vssps.visualstudio.com/"

$headers = @{
    'Authorization' = "Bearer $($token.Token)"
    '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)"
}

Excluir item de trabalho (DELETE)

Remova um item de trabalho do seu projeto:

Exemplo de 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;
    }
}

Bibliotecas cliente .NET

Para aplicações .NET, utilize as bibliotecas cliente .NET do Azure DevOps para melhor segurança de tipos e desenvolvimento mais fácil.

Instalação

Adicione estes pacotes NuGet ao seu projeto:

<PackageReference Include="Microsoft.TeamFoundationServer.Client" Version="19.232.1" />
<PackageReference Include="Microsoft.VisualStudio.Services.Client" Version="19.232.1" />
<PackageReference Include="Microsoft.Identity.Client" Version="4.67.2" />

Obtenha projetos usando o cliente .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;
    }
}

Criar item de trabalho usando o cliente .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;
    }
}

Tratamento de erros

Sempre implemente o tratamento adequado de erros em seus aplicativos:

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}");
}

Melhores práticas

  • Use o Microsoft Entra ID: Use a autenticação Microsoft Entra ID em vez de PATs para aplicações de produção.
  • Use HTTPS: Use sempre ligações seguras para chamadas API.
  • Lidar com limitações de taxa: Implementar lógica de retentativa com espera exponencial.
  • Respostas de cache: Armazenar dados frequentemente acedidos para reduzir chamadas de API.
  • Use versões específicas da API: Fixe para versões específicas para evitar alterações graves.
  • Validar entradas: Valide sempre as entradas do utilizador antes de fazer chamadas à API.
  • Registar adequadamente: Registar as interações da API para debugging, mas jamais registar credenciais.
  • Gestão de tokens: Implementar uma lógica adequada de cache e atualização de tokens para os tokens Microsoft Entra ID.

Usar IA para gerar código API REST

Se ligar o Azure DevOps MCP Server ao seu agente de IA em modo agente, pode usar prompts em linguagem natural para gerar código API REST para Azure DevOps.

Tarefa Exemplo de prompt
Listar projetos Show me how to list all projects in my Azure DevOps organization using the REST API with Microsoft Entra ID authentication in C#
Criar um item de trabalho Write a REST API call to create a bug in Azure DevOps with proper authentication headers and JSON-patch body
Obtenha repositórios Git Create a C# HttpClient example that retrieves Git repositories from Azure DevOps using a Bearer token from MSAL
Atualizar campos do item de trabalho Show me how to update work item fields using the Azure DevOps REST API PATCH method with proper content type headers
Consultar com WIQL Write a REST API call to execute a WIQL query against Azure DevOps and deserialize the response
Gerir a paginação Show me how to handle continuation tokens when listing Azure DevOps resources with the REST API in C#

Observação

O modo Agente e o Servidor MCP usam linguagem natural, por isso pode ajustar estes prompts ou fazer perguntas de seguimento para refinar os resultados.