From 183fa0090eac5d2303669719254ec13b64236b8a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 01:19:42 +0000 Subject: [PATCH 1/6] Initial plan From 8d7f0da0a7ac52e55b0cf3926cb6328b4bb19c96 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 01:28:17 +0000 Subject: [PATCH 2/6] Add how-to document for customizing ARM long-running operations Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com> --- .../howtos/ARM/long-running-operations.md | 243 ++++++++++++++++++ 1 file changed, 243 insertions(+) create mode 100644 website/src/content/docs/docs/howtos/ARM/long-running-operations.md diff --git a/website/src/content/docs/docs/howtos/ARM/long-running-operations.md b/website/src/content/docs/docs/howtos/ARM/long-running-operations.md new file mode 100644 index 0000000000..ea24f9df6e --- /dev/null +++ b/website/src/content/docs/docs/howtos/ARM/long-running-operations.md @@ -0,0 +1,243 @@ +--- +title: Customizing Long-Running Operations +description: How to customize LRO headers for ARM operations using standard templates +llmstxt: true +--- + +ARM long-running (asynchronous) operation templates allow you to customize the LRO headers returned +in the `202 Accepted` response, while retaining the correct `finalResult` value that matches the +result of the operation. This is done using the `LroHeaders` template parameter available on all +async operation templates. + +## LRO Header Types + +The `Azure.ResourceManager` library provides the following header models for long-running operations: + +| Header Model | Description | +| ------------------------- | ----------------------------------------------------------------------- | +| `ArmAsyncOperationHeader` | Provides the `Azure-AsyncOperation` header for polling | +| `ArmLroLocationHeader` | Provides the `Location` header for polling | +| `ArmCombinedLroHeaders` | Provides both `Azure-AsyncOperation` and `Location` headers for polling | + +Each header model accepts a `FinalResult` parameter that indicates the type of the logical result +of the operation. It is important that this value matches what the operation actually returns. + +## CreateOrUpdate (PUT) + +The `ArmResourceCreateOrReplaceAsync` and `ArmResourceCreateOrUpdateAsync` templates use +`ArmAsyncOperationHeader` by default with the resource as the final result. + +### Default + +```typespec +op createOrUpdate is ArmResourceCreateOrReplaceAsync; +``` + +The default `LroHeaders` for PUT is: + +``` +ArmAsyncOperationHeader & Azure.Core.Foundations.RetryAfterHeader +``` + +### Customizing to use a Location header + +To use a `Location` header instead of `Azure-AsyncOperation`, override the `LroHeaders` parameter. +Make sure `FinalResult` is set to the resource type so that the final polling result is correct: + +```typespec +op createOrUpdate is ArmResourceCreateOrReplaceAsync< + MyResource, + LroHeaders = ArmLroLocationHeader< + Azure.Core.StatusMonitorPollingOptions, + MyResource, + string + > & + Azure.Core.Foundations.RetryAfterHeader +>; +``` + +### Customizing to use both headers + +To return both `Azure-AsyncOperation` and `Location` headers, use `ArmCombinedLroHeaders`. Set +`FinalResult` to the resource type: + +```typespec +op createOrUpdate is ArmResourceCreateOrReplaceAsync< + MyResource, + LroHeaders = ArmCombinedLroHeaders & + Azure.Core.Foundations.RetryAfterHeader +>; +``` + +## Update (PATCH) + +The `ArmResourcePatchAsync` and `ArmCustomPatchAsync` templates use `ArmLroLocationHeader` by +default with the resource as the final result. + +### Default + +```typespec +op update is ArmResourcePatchAsync; +``` + +The default `LroHeaders` for PATCH is: + +``` +ArmLroLocationHeader, MyResource, string> + & Azure.Core.Foundations.RetryAfterHeader +``` + +### Customizing to use an Azure-AsyncOperation header + +To use an `Azure-AsyncOperation` header instead of `Location`, override the `LroHeaders` parameter. +Set `FinalResult` to the resource type: + +```typespec +op update is ArmResourcePatchAsync< + MyResource, + MyResourceProperties, + LroHeaders = ArmAsyncOperationHeader & + Azure.Core.Foundations.RetryAfterHeader +>; +``` + +### Customizing to use both headers + +To return both headers, use `ArmCombinedLroHeaders`. Set `FinalResult` to the resource type: + +```typespec +op update is ArmResourcePatchAsync< + MyResource, + MyResourceProperties, + LroHeaders = ArmCombinedLroHeaders & + Azure.Core.Foundations.RetryAfterHeader +>; +``` + +## Delete (DELETE) + +The `ArmResourceDeleteWithoutOkAsync` template uses `ArmLroLocationHeader` by default with `void` +as the final result, since delete operations do not return a resource body on completion. + +### Default + +```typespec +op delete is ArmResourceDeleteWithoutOkAsync; +``` + +The default `LroHeaders` for DELETE is: + +``` +ArmLroLocationHeader & Azure.Core.Foundations.RetryAfterHeader +``` + +### Customizing to use an Azure-AsyncOperation header + +To use an `Azure-AsyncOperation` header instead of `Location`, override the `LroHeaders` parameter. +Keep `FinalResult` as `void` because delete operations do not return a resource body: + +```typespec +op delete is ArmResourceDeleteWithoutOkAsync< + MyResource, + LroHeaders = ArmAsyncOperationHeader & Azure.Core.Foundations.RetryAfterHeader +>; +``` + +### Customizing to use both headers + +To return both headers, use `ArmCombinedLroHeaders`. Keep `FinalResult` as `void`: + +```typespec +op delete is ArmResourceDeleteWithoutOkAsync< + MyResource, + LroHeaders = ArmCombinedLroHeaders & + Azure.Core.Foundations.RetryAfterHeader +>; +``` + +## Resource Action (POST) + +The `ArmResourceActionAsync` template uses `ArmLroLocationHeader` by default. The `FinalResult` +should match the response type of the action. For actions that return no content, use +`ArmResourceActionNoResponseContentAsync` where `FinalResult` defaults to `void`. + +### Default action with response + +```typespec +op startMigration is ArmResourceActionAsync; +``` + +The default `LroHeaders` for a POST action is: + +``` +ArmLroLocationHeader< + Azure.Core.StatusMonitorPollingOptions, + MigrationResponse, + string +> & Azure.Core.Foundations.RetryAfterHeader +``` + +### Default action with no response content + +```typespec +op restart is ArmResourceActionNoResponseContentAsync; +``` + +The default `LroHeaders` for a no-content POST action is: + +``` +ArmLroLocationHeader< + Azure.Core.StatusMonitorPollingOptions, + void, + string +> & Azure.Core.Foundations.RetryAfterHeader +``` + +### Customizing to use an Azure-AsyncOperation header + +Override the `LroHeaders` parameter. Set `FinalResult` to match the response type of the action: + +```typespec +op startMigration is ArmResourceActionAsync< + MyResource, + MigrationRequest, + MigrationResponse, + LroHeaders = ArmAsyncOperationHeader & + Azure.Core.Foundations.RetryAfterHeader +>; +``` + +For an action with no response content, set `FinalResult` to `void`: + +```typespec +op restart is ArmResourceActionNoResponseContentAsync< + MyResource, + RestartRequest, + LroHeaders = ArmAsyncOperationHeader & Azure.Core.Foundations.RetryAfterHeader +>; +``` + +### Customizing to use both headers + +To return both headers, use `ArmCombinedLroHeaders`. Set `FinalResult` to match the response type: + +```typespec +op startMigration is ArmResourceActionAsync< + MyResource, + MigrationRequest, + MigrationResponse, + LroHeaders = ArmCombinedLroHeaders & + Azure.Core.Foundations.RetryAfterHeader +>; +``` + +For an action with no response content: + +```typespec +op restart is ArmResourceActionNoResponseContentAsync< + MyResource, + RestartRequest, + LroHeaders = ArmCombinedLroHeaders & + Azure.Core.Foundations.RetryAfterHeader +>; +``` From 46ce5cfda0517e82e24a25218de08ccd76189173 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 01:59:08 +0000 Subject: [PATCH 3/6] Simplify LRO header template usage with named FinalResult parameter Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com> --- .../howtos/ARM/long-running-operations.md | 21 ++++--------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/website/src/content/docs/docs/howtos/ARM/long-running-operations.md b/website/src/content/docs/docs/howtos/ARM/long-running-operations.md index ea24f9df6e..6d64d9ce24 100644 --- a/website/src/content/docs/docs/howtos/ARM/long-running-operations.md +++ b/website/src/content/docs/docs/howtos/ARM/long-running-operations.md @@ -47,11 +47,7 @@ Make sure `FinalResult` is set to the resource type so that the final polling re ```typespec op createOrUpdate is ArmResourceCreateOrReplaceAsync< MyResource, - LroHeaders = ArmLroLocationHeader< - Azure.Core.StatusMonitorPollingOptions, - MyResource, - string - > & + LroHeaders = ArmLroLocationHeader & Azure.Core.Foundations.RetryAfterHeader >; ``` @@ -83,8 +79,7 @@ op update is ArmResourcePatchAsync; The default `LroHeaders` for PATCH is: ``` -ArmLroLocationHeader, MyResource, string> - & Azure.Core.Foundations.RetryAfterHeader +ArmLroLocationHeader & Azure.Core.Foundations.RetryAfterHeader ``` ### Customizing to use an Azure-AsyncOperation header @@ -170,11 +165,7 @@ op startMigration is ArmResourceActionAsync, - MigrationResponse, - string -> & Azure.Core.Foundations.RetryAfterHeader +ArmLroLocationHeader & Azure.Core.Foundations.RetryAfterHeader ``` ### Default action with no response content @@ -186,11 +177,7 @@ op restart is ArmResourceActionNoResponseContentAsync, - void, - string -> & Azure.Core.Foundations.RetryAfterHeader +ArmLroLocationHeader & Azure.Core.Foundations.RetryAfterHeader ``` ### Customizing to use an Azure-AsyncOperation header From accd7f93b3ebbf1bd9e665fa259a38ca1d01e36d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 02:00:49 +0000 Subject: [PATCH 4/6] Fix intro to clarify LRO headers appear in 201 for PUT, 202 for others Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com> --- .../docs/docs/howtos/ARM/long-running-operations.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/website/src/content/docs/docs/howtos/ARM/long-running-operations.md b/website/src/content/docs/docs/howtos/ARM/long-running-operations.md index 6d64d9ce24..959c33a35e 100644 --- a/website/src/content/docs/docs/howtos/ARM/long-running-operations.md +++ b/website/src/content/docs/docs/howtos/ARM/long-running-operations.md @@ -5,9 +5,10 @@ llmstxt: true --- ARM long-running (asynchronous) operation templates allow you to customize the LRO headers returned -in the `202 Accepted` response, while retaining the correct `finalResult` value that matches the -result of the operation. This is done using the `LroHeaders` template parameter available on all -async operation templates. +in the initial response, while retaining the correct `finalResult` value that matches the result of +the operation. This is done using the `LroHeaders` template parameter available on all async +operation templates. The headers appear in the `201 Created` response for PUT operations and in the +`202 Accepted` response for PATCH, DELETE, and POST operations. ## LRO Header Types From 03c78f8a0d1328027ec2afed1dc25493cdfef1a5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 02:08:20 +0000 Subject: [PATCH 5/6] Simplify ArmCombinedLroHeaders usage to use named FinalResult parameter Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com> --- .../docs/docs/howtos/ARM/long-running-operations.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/website/src/content/docs/docs/howtos/ARM/long-running-operations.md b/website/src/content/docs/docs/howtos/ARM/long-running-operations.md index 959c33a35e..5d34bf6127 100644 --- a/website/src/content/docs/docs/howtos/ARM/long-running-operations.md +++ b/website/src/content/docs/docs/howtos/ARM/long-running-operations.md @@ -61,7 +61,7 @@ To return both `Azure-AsyncOperation` and `Location` headers, use `ArmCombinedLr ```typespec op createOrUpdate is ArmResourceCreateOrReplaceAsync< MyResource, - LroHeaders = ArmCombinedLroHeaders & + LroHeaders = ArmCombinedLroHeaders & Azure.Core.Foundations.RetryAfterHeader >; ``` @@ -105,7 +105,7 @@ To return both headers, use `ArmCombinedLroHeaders`. Set `FinalResult` to the re op update is ArmResourcePatchAsync< MyResource, MyResourceProperties, - LroHeaders = ArmCombinedLroHeaders & + LroHeaders = ArmCombinedLroHeaders & Azure.Core.Foundations.RetryAfterHeader >; ``` @@ -146,7 +146,7 @@ To return both headers, use `ArmCombinedLroHeaders`. Keep `FinalResult` as `void ```typespec op delete is ArmResourceDeleteWithoutOkAsync< MyResource, - LroHeaders = ArmCombinedLroHeaders & + LroHeaders = ArmCombinedLroHeaders & Azure.Core.Foundations.RetryAfterHeader >; ``` @@ -214,7 +214,7 @@ op startMigration is ArmResourceActionAsync< MyResource, MigrationRequest, MigrationResponse, - LroHeaders = ArmCombinedLroHeaders & + LroHeaders = ArmCombinedLroHeaders & Azure.Core.Foundations.RetryAfterHeader >; ``` @@ -225,7 +225,7 @@ For an action with no response content: op restart is ArmResourceActionNoResponseContentAsync< MyResource, RestartRequest, - LroHeaders = ArmCombinedLroHeaders & + LroHeaders = ArmCombinedLroHeaders & Azure.Core.Foundations.RetryAfterHeader >; ``` From 4d3f3b021a5ec1b11b0660bd22bfe26b0f0e282e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 02:35:00 +0000 Subject: [PATCH 6/6] Run pnpm format on changed markdown files Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com> --- .../content/docs/docs/howtos/ARM/long-running-operations.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/website/src/content/docs/docs/howtos/ARM/long-running-operations.md b/website/src/content/docs/docs/howtos/ARM/long-running-operations.md index 5d34bf6127..17b5a0ee35 100644 --- a/website/src/content/docs/docs/howtos/ARM/long-running-operations.md +++ b/website/src/content/docs/docs/howtos/ARM/long-running-operations.md @@ -146,8 +146,7 @@ To return both headers, use `ArmCombinedLroHeaders`. Keep `FinalResult` as `void ```typespec op delete is ArmResourceDeleteWithoutOkAsync< MyResource, - LroHeaders = ArmCombinedLroHeaders & - Azure.Core.Foundations.RetryAfterHeader + LroHeaders = ArmCombinedLroHeaders & Azure.Core.Foundations.RetryAfterHeader >; ``` @@ -225,7 +224,6 @@ For an action with no response content: op restart is ArmResourceActionNoResponseContentAsync< MyResource, RestartRequest, - LroHeaders = ArmCombinedLroHeaders & - Azure.Core.Foundations.RetryAfterHeader + LroHeaders = ArmCombinedLroHeaders & Azure.Core.Foundations.RetryAfterHeader >; ```