|
1 | 1 | # Microsoft Azure REST API Guidelines
|
| 2 | + |
| 3 | +<!-- cspell:ignore autorest, BYOS, etag, idempotency, maxpagesize, innererror --> |
| 4 | + |
2 | 5 | ## History
|
3 | 6 |
|
4 | 7 | | Date | Notes |
|
5 | 8 | | ----------- | -------------------------------------------------------------- |
|
| 9 | +| 2022-Jul-15 | Update guidance on long-running operations | |
6 | 10 | | 2022-May-11 | Drop guidance on version discovery |
|
7 | 11 | | 2022-Mar-29 | Add guidelines about using durations |
|
8 | 12 | | 2022-Mar-25 | Update guideline for date values in headers to follow RFC 7231 |
|
@@ -135,7 +139,7 @@ GET | Read (i.e. list) a resource collection | `200-OK`
|
135 | 139 | GET | Read the resource | `200-OK`
|
136 | 140 | DELETE | Remove the resource | `204-No Content`\; avoid `404-Not Found`
|
137 | 141 |
|
138 |
| -:white_check_mark: **DO** return status code `202-Accepted` and follow the guidance in [Long-Running Operations & Jobs](#long-running-operations--jobs) when a PUT, PATCH, POST, or DELETE method completes asynchronously. |
| 142 | +:white_check_mark: **DO** return status code `202-Accepted` and follow the guidance in [Long-Running Operations & Jobs](#long-running-operations--jobs) when a PUT, POST, or DELETE method completes asynchronously. |
139 | 143 |
|
140 | 144 | :white_check_mark: **DO** treat method names as case sensitive and should always be in uppercase
|
141 | 145 |
|
@@ -694,7 +698,11 @@ Azure services need to change over time. However, when changing a service, there
|
694 | 698 |
|
695 | 699 | :white_check_mark: **DO** review any API changes with the Azure API Stewardship Board
|
696 | 700 |
|
697 |
| -:white_check_mark: **DO** use an `api-version` query parameter with a `YYYY-MM-DD` date value, with a `-preview` suffix for a preview service. |
| 701 | +Clients specify the version of the API to be used in every request to the service, even requests to an `Operation-Location` or `nextLink` URL returned by the service. |
| 702 | + |
| 703 | +:white_check_mark: **DO** use a required query parameter named `api-version` on every operation for the client to specify the API version. |
| 704 | + |
| 705 | +:white_check_mark: **DO** use `YYYY-MM-DD` date values, with a `-preview` suffix for preview versions, as the valid values for `api-version`. |
698 | 706 |
|
699 | 707 | ```text
|
700 | 708 | PUT https://service.azure.com/users/Jeff?api-version=2021-06-04
|
@@ -757,68 +765,99 @@ implemented as a _long-running operation (LRO)_. This allows clients to continue
|
757 | 765 | operation is being processed. The client obtains the outcome of the operation at some later time
|
758 | 766 | through another API call.
|
759 | 767 | See the [Long Running Operations section](./ConsiderationsForServiceDesign.md#long-running-operations) in
|
760 |
| -Considerations for Service Design for an introduction to the design of long running operations. |
| 768 | +Considerations for Service Design for an introduction to the design of long-running operations. |
761 | 769 |
|
762 | 770 | :white_check_mark: **DO** implement an operation as an LRO if the 99th percentile response time is greater than 1s.
|
763 | 771 |
|
| 772 | +:no_entry: **DO NOT** implement PATCH as an LRO. If LRO update is required it must be implemented with POST. |
| 773 | + |
764 | 774 | In rare instances where an operation may take a _very long_ time to complete, e.g. longer than 15 minutes,
|
765 | 775 | it may be better to expose this as a first class resource of the API rather than as an operation on another resource.
|
766 | 776 |
|
767 |
| -There are two basic patterns that can be used for long-running operations: |
768 |
| -1. Resource-based long-running operations (RELO) |
769 |
| -2. Long-running operations with status monitor |
| 777 | +There are two basic patterns for long-running operations in Azure. The first pattern is used for a POST and DELETE |
| 778 | +operations that initiate the LRO. These return a `202 Accepted` response with a JSON status monitor in the response body. |
| 779 | +The second pattern applies only in the case of a PUT operation to create a resource that also involves additional long-running processing. |
| 780 | +For guidance on when to use a specific pattern, please refer to [Considerations for Service Design, Long Running Operations](./ConsiderationsForServiceDesign.md#long-running-operations). |
| 781 | +These are described in the following two sections. |
| 782 | + |
| 783 | +#### POST or DELETE LRO pattern |
| 784 | + |
| 785 | +A POST or DELETE long-running operation accepts a request from the client to initiate the operation processing and returns |
| 786 | +a [status monitor](https://datatracker.ietf.org/doc/html/rfc7231#section-6.3.3) that reports the operation's progress. |
| 787 | + |
| 788 | +:no_entry: **DO NOT** use a long-running POST to create a resource -- use PUT as described below. |
| 789 | + |
| 790 | +:white_check_mark: **DO** allow the client to pass an `Operation-Id` header with an ID for the operation's status monitor. |
| 791 | + |
| 792 | +:white_check_mark: **DO** generate an ID (typically a GUID) for the status monitor if the `Operation-Id` header was not passed by the client. |
| 793 | + |
| 794 | +:white_check_mark: **DO** fail a request with a `400-BadRequest` if the `Operation-Id` header matches an existing operation unless the request is identical to the prior request (a retry scenario). |
| 795 | + |
| 796 | +:white_check_mark: **DO** perform as much validation as practical when initiating the operation to alert clients of errors early. |
| 797 | + |
| 798 | +:white_check_mark: **DO** return a `202-Accepted` status code from the request that initiates an LRO if the processing of the operation was successfully initiated (except for "PUT with additional processing" type LRO). |
| 799 | + |
| 800 | +:warning: **YOU SHOULD NOT** return any other `2xx` status code from the initial request of an LRO -- return `202-Accepted` and a status monitor even if processing was completed before the initiating request returns. |
| 801 | + |
| 802 | +:white_check_mark: **DO** return a status monitor in the response body as described in [Obtaining status and results of long-running operations](#obtaining-status-and-results-of-long-running-operations). |
| 803 | + |
| 804 | +:ballot_box_with_check: **YOU SHOULD** include an `Operation-Location` header in the response with the absolute URL of the status monitor for the operation. |
770 | 805 |
|
771 |
| -:white_check_mark: **DO** use the RELO pattern when the operation is on a resource that contains a "status" property that can be used to obtain the outcome of the operation. |
| 806 | +:ballot_box_with_check: **YOU SHOULD** include the `api-version` query parameter in the `Operation-Location` header with the same version passed on the initial request if it is required by the get operation on the status monitor. |
772 | 807 |
|
773 |
| -:ballot_box_with_check: **YOU SHOULD** only use the status monitor LRO pattern when the RELO pattern is not applicable. |
| 808 | +:ballot_box_with_check: **YOU SHOULD** allow any valid value of the `api-version` query parameter to be used in the get operation on the status monitor. |
774 | 809 |
|
775 |
| -#### Resource-based long-running operations |
| 810 | +#### PUT operation with additional long-running processing |
776 | 811 |
|
777 |
| -Some common situations where the RELO pattern should be used: |
778 |
| -1. A "create" operation (PUT, PATCH, or POST) for a resource where the basic structure of the resource is created immediately and includes a status field that indicates when the create has completed, e.g. "provisioning" -> "active". |
779 |
| -2. An action operation for a resource where both the initiation of the action and the completion of the action cause a change to the "status" property of the resource. |
| 812 | +For a PUT (create or replace) with additional long-running processing: |
780 | 813 |
|
781 |
| -:white_check_mark: **DO** return a `200-OK` response, `201-Created` for create operations, from the request that initiates the operation. The response body should contain a representation of the resource that clearly indicates that the operation has been accepted or started. |
| 814 | +:white_check_mark: **DO** allow the client to pass an `Operation-Id` header with a ID for the status monitor for the operation. |
782 | 815 |
|
783 |
| -:white_check_mark: **DO** support a get method on the resource that returns a representation of the resource including the status field that indicates when the operation has completed. |
| 816 | +:white_check_mark: **DO** generate an ID (typically a GUID) for the status monitor if the `Operation-Id` header was not passed by the client. |
784 | 817 |
|
785 |
| -:white_check_mark: **DO** define the "status" field of the resource as an enum with all the values it may contain including the "terminal" values "Succeeded", "Failed", and "Canceled". See [Enums & SDKs](#enums--sdks-client-libraries). |
| 818 | +:white_check_mark: **DO** fail a request with a `400-BadRequest` if the `Operation-Id` header that matches an existing operation unless the request is identical to the prior request (a retry scenario). |
786 | 819 |
|
787 |
| -:ballot_box_with_check: **YOU SHOULD** use the name `status` for the "status" field of the resource. |
| 820 | +:white_check_mark: **DO** perform as much validation as practical when initiating the operation to alert clients of errors early. |
788 | 821 |
|
789 |
| -#### Long-running operations with status monitor |
| 822 | +:white_check_mark: **DO** return a `201-Created` status code for create or `200-OK` for replace from the initial request with a representation of the resource if the resource was created successfully. |
790 | 823 |
|
791 |
| -In a long-running operation with status monitor, the client makes a request to initiate the operation processing and receives a URL in the response where it can obtain the operation results. The [HTTP specification](https://datatracker.ietf.org/doc/html/rfc7231#section-6.3.3) calls the target of this URL a "status monitor". |
| 824 | +:white_check_mark: **DO** include an `Operation-Id` header in the response with the ID of the status monitor for the operation. |
792 | 825 |
|
793 |
| -:white_check_mark: **DO** return a `202-Accepted` status code from the request that initiates an LRO with status monitor if the processing of the operation was successfully initiated. |
| 826 | +:white_check_mark: **DO** include response headers with any additional values needed for a GET request to the status monitor (e.g. location). |
794 | 827 |
|
795 |
| -:white_check_mark: **DO** perform as much validation of the initial request as practical and return an error response immediately when appropriate (without starting the operation). |
| 828 | +:ballot_box_with_check: **YOU SHOULD** include an `Operation-Location` header in the response with the absolute URL of the status monitor for the operation. |
796 | 829 |
|
797 |
| -:white_check_mark: **DO** return the status monitor URL in the `Operation-Location` response header. |
| 830 | +:ballot_box_with_check: **YOU SHOULD** include the `api-version` query parameter in the `Operation-Location` header with the same version passed on the initial request if it is required by the get operation on the status monitor. |
798 | 831 |
|
799 |
| -:white_check_mark: **DO** support the `get` method on the status monitor endpoint that returns a `200-OK` response with a response body that contains the completion status of the operation with sufficient information to diagnose any potential failures. |
| 832 | +:ballot_box_with_check: **YOU SHOULD** allow any valid value of the `api-version` query parameter to be used in the get operation on the status monitor. |
800 | 833 |
|
801 |
| -:white_check_mark: **DO** include a field in the status monitor resource named `status` indicating the operation's status. This field should be a string with well-defined values. Indicate the terminal state using "Succeeded", "Failed", or "Canceled". |
| 834 | +#### Obtaining status and results of long-running operations |
802 | 835 |
|
803 |
| -:white_check_mark: **DO** include a field in the status monitor named `error` to contain error information -- minimally `code` and `message` fields -- when an operation fails. |
| 836 | +For all long-running operations, the client will issue a GET on a status monitor resource to obtain the current status of the operation. |
804 | 837 |
|
805 |
| -:white_check_mark: **DO** retain the status monitor resource for some documented period of time (at least 24 hours) after the operation completes. |
| 838 | +:white_check_mark: **DO** support the GET method on the status monitor endpoint that returns a `200-OK` response with the current state of the status monitor. |
806 | 839 |
|
807 |
| -:white_check_mark: **DO** include a `Retry-After` header in the response to the initiating request and requests to the operation-location URL. The value of this header should be an integer number of seconds to wait before making the next request to the operation-location URL. |
| 840 | +:white_check_mark: **DO** return a status monitor in the response body that conforms with the following structure: |
808 | 841 |
|
809 |
| -:heavy_check_mark: **YOU MAY** support a `get` method on the status monitor collection URL that returns a list of status monitors for all recently initiated operations. |
| 842 | +**OperationStatus** : Object |
810 | 843 |
|
811 |
| -:warning: **YOU SHOULD NOT** return any other `2xx` status code from the initial request of a status-monitor LRO -- return `202-Accepted` and a status monitor URL even if processing was completed before the initiating request returns. |
| 844 | +Property | Type | Required | Description |
| 845 | +-------- | ----------- | :------: | ----------- |
| 846 | +`id` | string | true | The unique id of the operation |
| 847 | +`status` | string | true | enum that includes terminal values "Succeeded", "Failed", "Canceled" |
| 848 | +`error` | ErrorDetail | | Error object that describes the error when status is "Failed" |
| 849 | +`result` | object | | Only for POST action-type LRO, the results of the operation when completed successfully |
| 850 | +additional<br/>properties | | | Additional named or dynamic properties of the operation |
812 | 851 |
|
813 |
| -:no_entry: **DO NOT** return any data in the response body of a `202-Accepted` response. |
| 852 | +:white_check_mark: **DO** include the `id` of the operation and any other values needed for the client to form a GET request to the status monitor (e.g. a `location` path parameter). |
814 | 853 |
|
815 |
| -Previous Azure guidelines specified "Azure-AsyncOperation" as the name of the response header containing the status monitor URL. |
| 854 | +:white_check_mark: **DO** include a `Retry-After` header in the response to GET requests to the status monitor if the operation is not complete. The value of this header should be an integer number of seconds to wait before making the next request to the status monitor. |
816 | 855 |
|
817 |
| -:white_check_mark: **DO** return **both** `Azure-AsyncOperation` and `Operation-Location` headers if your service previously returned `Azure-AsyncOperation`, even though they are redundant, so that existing clients will continue to operate. |
| 856 | +:white_check_mark: **DO** include the `result` property (if any) in the status monitor for a POST action-type long-running operation when the operation completes successfully. |
818 | 857 |
|
819 |
| -:white_check_mark: **DO** return the same value for **both** headers. |
| 858 | +:no_entry: **DO NOT** include a `result` property in the status monitor for a long-running operation that is not a POST action-type long-running operation. |
820 | 859 |
|
821 |
| -:white_check_mark: **DO** look for **both** headers in client code, preferring the `Operation-Location` header. |
| 860 | +:white_check_mark: **DO** retain the status monitor resource for some publicly documented period of time (at least 24 hours) after the operation completes. |
822 | 861 |
|
823 | 862 | ### Bring your own Storage
|
824 | 863 | When implementing your service, it is very common to store and retrieve data and files. When you encounter this scenario, avoid implementing your own storage strategy and instead use Azure Bring Your Own Storage (BYOS). BYOS provides significant benefits to service implementors, e.g. security, an aggressively optimized frontend, uptime, etc.
|
@@ -847,7 +886,7 @@ It is not uncommon to rely on other services, e.g. storage, when implementing yo
|
847 | 886 | Generally speaking, there are two patterns that you will encounter when working with files; single file access, and file collections.
|
848 | 887 |
|
849 | 888 | ##### Single file access
|
850 |
| -Desiging an API for accessing a single file, depending on your scenario, is relatively straight forward. |
| 889 | +Designing an API for accessing a single file, depending on your scenario, is relatively straight forward. |
851 | 890 |
|
852 | 891 | :heavy_check_mark: **YOU MAY** use a Shared Access Signature [SAS](https://docs.microsoft.com/en-us/azure/storage/common/storage-sas-overview) to provide access to a single file. SAS is considered the minimum security for files and can be used in lieu of, or in addition to, RBAC.
|
853 | 892 |
|
|
0 commit comments