Public/Web/Invoke-Api.ps1
function Invoke-Api { <# .SYNOPSIS Helper function for calling a web service returning a single object. For example, for a project detail. .PARAMETER ApiCredential Credential to use for authentication. If not specified, $global:AzureDevOpsApi_ApiCredential (set by Set-AzureDevopsVariables) is used. .PARAMETER ApiVersion Requested version of Azure DevOps API. If not specified, $global:AzureDevOpsApi_ApiVersion (set by Set-AzureDevopsVariables) is used. .PARAMETER Uri Web service call address including query parameters. .PARAMETER Body An object that can be POSTed as a request. .PARAMETER Method The HTTP method to use. If not specified, it is decided according to whether the Body parameter is given. If not, GET is used, otherwise POST. .PARAMETER ContentType The Content-Type header when sending Body. Default is 'application/json'. .PARAMETER AsHashTable If specified, deserializes the JSON response to a hashtable, instead of standard [PSObject]. .PARAMETER RetryCount The maximum number of retry attempts for transient failures. Default is 3. .PARAMETER RetryDelay The base delay in seconds between retry attempts. Default is 1 second. .PARAMETER DisableRetry Disables retry logic completely. #> [CmdletBinding()] param( [AllowNull()] [PSTypeName('PSTypeNames.AzureDevOpsApi.ApiCredential')] [PSCustomObject] $ApiCredential, $ApiVersion, $Uri, $Body, $Method, $ContentType, [switch] $AsHashTable, [ValidateRange(0, 10)] [int] $RetryCount, [ValidateRange(0.1, 300)] [double] $RetryDelay, [switch] $DisableRetry ) begin { # Use global configuration as defaults if not specified if (-not $PSBoundParameters.ContainsKey('RetryCount')) { $RetryCount = $global:AzureDevOpsApi_RetryConfig.RetryCount } if (-not $PSBoundParameters.ContainsKey('RetryDelay')) { $RetryDelay = $global:AzureDevOpsApi_RetryConfig.RetryDelay } if (-not $PSBoundParameters.ContainsKey('DisableRetry')) { $DisableRetry = $global:AzureDevOpsApi_RetryConfig.DisableRetry } } process { # Determine whether relative or absolute uri was given if (-not ([Uri]::new($Uri, [UriKind]::RelativeOrAbsolute)).IsAbsoluteUri) { throw "Uri must be absolute. Given: $Uri" } # Use global variables if not specified $ApiVersion = Use-ApiVersion -ApiVersion $ApiVersion # Add api version parameter $genericUrl = Add-QueryParameter ` -Uri $Uri ` -Parameters @{ 'api-version' = $ApiVersion } try { # Call the api $httpResponse = Invoke-CustomWebRequest ` -ApiCredential $ApiCredential ` -Uri $genericUrl ` -Body $Body ` -Method $Method ` -ContentType $ContentType ` -RetryCount $RetryCount ` -RetryDelay $RetryDelay ` -DisableRetry:$DisableRetry } catch { # In some cases 404 can be returned # for example requesting work item before its creation date time using AsOf parameter # Standard WebExceptions if ($ErrorActionPreference -eq 'Stop') { Assert-HttpResponse -Error $_ return } if ($_.Exception.Response.StatusCode -eq 404) { return } # For testing purposes, since I can not simulate standard WebExceptions thrown in Powershell 5 if ($_.TargetObject.StatusCode -eq 404) { return } } $result = $httpResponse.Content ` | ConvertFrom-JsonCustom -AsHashtable:$AsHashTable if ($null -ne $result) { return $result } } } Set-Alias -Name Invoke-ApiGet -Value Invoke-Api |