Compartilhar via


Exemplos de API REST para Azure DevOps

Azure DevOps Services | Azure DevOps Server | Azure DevOps Server 2022

Este artigo fornece exemplos práticos de API REST para serviços de Azure DevOps. Esses exemplos demonstram operações comuns, como recuperar projetos, gerenciar itens de trabalho e usar padrões de autenticação seguros com Microsoft Entra ID.

Importante

Considere usar os mais seguros tokens Microsoft Entra em relação aos tokens de acesso pessoal de maior risco. Para obter mais informações, consulte Reduzir o uso do PAT. Examine as diretrizes de autenticação para escolher o mecanismo de autenticação correto para suas necessidades.

Visão geral da autenticação

Azure DevOps APIs REST dão suporte a vários métodos de autenticação:

  • Microsoft Entra ID - Recomendado para aplicativos de produção (usados nestes exemplos)
  • PATs (Tokens de Acesso Pessoal) – Autenticação simples para scripts e testes
  • Entidades de serviço e identidades gerenciadas – Para cenários automatizados

Dica

Você pode usar a IA para ajudar nessa tarefa mais adiante neste artigo ou consulte Ativar a assistência de IA com o Azure DevOps Server MCP para começar.

autenticação Microsoft Entra ID

Para autenticação do Microsoft Entra ID, registre um aplicativo e obtenha um token de acesso. Veja como autenticar usando a MSAL (Biblioteca de Autenticação da Microsoft):

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 de 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 de 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 o item de trabalho (PATCH)

Atualize 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 de 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 de cliente .NET

Para aplicativos .NET, use as bibliotecas de cliente Azure DevOps .NET para melhorar a segurança do tipo e facilitar o desenvolvimento.

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" />

Obter projetos usando .NET cliente

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 .NET cliente

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

Práticas recomendadas

  • Use o Microsoft Entra ID: use a autenticação do Microsoft Entra ID em vez de PATs para aplicativos de produção.
  • Use HTTPS: use sempre conexões seguras para chamadas à API.
  • Lidar com limites de taxa: implementar lógica de repetição com retrocesso exponencial.
  • Respostas de cache: armazene dados acessados com frequência para reduzir as chamadas à API.
  • Use versões de API específicas: fixe em versões específicas para evitar alterações significativas.
  • Validar entradas: sempre valide as entradas do usuário antes de fazer chamadas à API.
  • Registre-se adequadamente: registre interações de API para depuração, mas nunca registre credenciais.
  • Gerenciamento de token: implemente o cache adequado de tokens e a lógica de atualização para tokens do Microsoft Entra ID.

Usar a IA para gerar o código da API REST

Se você conectar o Servidor MCP do Azure DevOps ao agente de IA no modo de agente, poderá usar prompts de linguagem natural para gerar o código da API REST para o Azure DevOps.

Tarefa Prompt de exemplo
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
Buscar repositórios Git Create a C# HttpClient example that retrieves Git repositories from Azure DevOps using a Bearer token from MSAL
Atualizar os 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
Consulta com WIQL Write a REST API call to execute a WIQL query against Azure DevOps and deserialize the response
Manipular paginação Show me how to handle continuation tokens when listing Azure DevOps resources with the REST API in C#

Observação

O modo de agente e o servidor MCP usam linguagem natural, para que você possa ajustar esses prompts ou fazer perguntas de acompanhamento para refinar os resultados.