Skip to content

Commit 0ab68b1

Browse files
authored
Merge pull request #337 from mikekistler/rip-1123
Update guideline for date values in headers to follow RFC 7231
2 parents 8465bf2 + 8121816 commit 0ab68b1

File tree

1 file changed

+30
-31
lines changed

1 file changed

+30
-31
lines changed

azure/Guidelines.md

Lines changed: 30 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33

44
| Date | Notes |
55
| ----------- | -------------------------------------------------------------- |
6-
| 2022-Feb-01 | Updated error guidance |
6+
| 2022-Mar-25 | Update guideline for date values in headers to follow RFC 7231 |
7+
| 2022-Feb-01 | Updated error guidance |
78
| 2021-Sep-11 | Add long-running operations guidance |
89
| 2021-Aug-06 | Updated Azure REST Guidelines per Azure API Stewardship Board. |
910
| 2020-Jul-31 | Added service advice for initial versions |
@@ -46,12 +47,12 @@ The Microsoft Azure Cloud platform exposes its APIs through the core building bl
4647

4748
### HTTP
4849
Azure services must adhere to the HTTP specification, [RFC7231](https://tools.ietf.org/html/rfc7231). This section further refines and constrains how service implementors should apply the constructs defined in the HTTP specification. It is therefore, important that you have a firm understanding of the following concepts:
49-
- [Uniform Resource Locators (URLs)](URLS)
50-
- HTTP Methods
51-
- Request & Response Headers
52-
- Bodies
5350

54-
### Uniform Resource Locators (URLs)
51+
- [Uniform Resource Locators (URLs)](#uniform-resource-locators-urls)
52+
- [HTTP Request / Response Pattern](#http-request--response-pattern)
53+
- [HTTP Query Parameters and Header Values](#http-query-parameters-and-header-values)
54+
55+
#### Uniform Resource Locators (URLs)
5556

5657
A Uniform Resource Locator (URL) is how developers access the resources of your service. Ultimately, URLs are how developers form a cognitive model of your service's resources.
5758

@@ -88,8 +89,6 @@ Some customer-provided path segment values may be compared case-insensitivity if
8889

8990
:heavy_check_mark: **YOU MAY** use these other characters in the URL path but they will likely require %-encoding [[RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986#section-2.1)]: `/ ? # [ ] @ ! $ & ' ( ) * + , ; =`
9091

91-
#### Direct Endpoint URLs
92-
9392
:heavy_check_mark: **YOU MAY** support a direct endpoint URL for performance/routing:
9493
```text
9594
https://<tenant>-<service-root>.<service>.<cloud>/...
@@ -103,16 +102,16 @@ Examples:
103102
:white_check_mark: **DO** return URLs in response headers/bodies in a consistent form regardless of the URL used to reach the resource. Either always a UUID for `<tenant>` or always a single verified domain.
104103

105104
:heavy_check_mark: **YOU MAY** use URLs as values
106-
```http
105+
```text
107106
https://api.contoso.com/items?url=https://resources.contoso.com/shoes/fancy
108107
```
109108

110-
### HTTP Request / Response Pattern
109+
#### HTTP Request / Response Pattern
111110
The HTTP Request / Response pattern dictates how your API behaves. For example: POST methods that create resources must be idempotent, GET method results may be cached, the If-Modified and ETag headers offer optimistic concurrency. The URL of a service, along with its request/response bodies, establishes the overall contract that developers have with your service. As a service provider, how you manage the overall request / response pattern should be one of the first implementation decisions you make.
112111

113112
Cloud applications embrace failure. Therefore, to enable customers to write fault-tolerant applications, _all_ service operations (including POST) **must** be idempotent. Implementing services in an idempotent manner, with an "exactly once" semantic, enables developers to retry requests without the risk of unintended consequences.
114113

115-
#### Exactly Once Behavior = Client Retries & Service Idempotency
114+
##### Exactly Once Behavior = Client Retries & Service Idempotency
116115

117116
:white_check_mark: **DO** ensure that _all_ HTTP methods are idempotent.
118117

@@ -146,7 +145,7 @@ DELETE | Remove the resource | `204-No Content`\; avoid `404-Not Found`
146145

147146
:white_check_mark: **DO** support caching and optimistic concurrency by honoring the the `If-Match`, `If-None-Match`, if-modified-since, and if-unmodified-since request headers and by returning the ETag and last-modified response headers
148147

149-
### HTTP Query Parameters and Header Values
148+
#### HTTP Query Parameters and Header Values
150149
Because information in the service URL, as well as the request / response, are strings, there must be a predictable, well-defined scheme to convert strings to their corresponding values.
151150

152151
:white_check_mark: **DO** validate all query parameter and request header values and fail the operation with `400-Bad Request` if any value fails validation. Return an error response as described in the [Handling Errors](#Handling-errors) section indicating what is wrong so customer can diagnose the issue and fix it themselves.
@@ -160,7 +159,7 @@ Integer | -2<sup>53</sup>+1 to +2<sup>53</sup>-1 (for consistency with JSON li
160159
Float | [IEEE-754 binary64](https://en.wikipedia.org/wiki/Double-precision_floating-point_format)
161160
String | (Un)quoted?, max length, legal characters, case-sensitive, multiple delimiter
162161
UUID | 123e4567-e89b-12d3-a456-426614174000 (no {}s, hyphens, case-insensitive) [RFC4122](https://datatracker.ietf.org/doc/html/rfc4122)
163-
Date/Time (Header) | Sun, 06 Nov 1994 08:49:37 GMT [RFC 1123, Section 5.2.14](https://datatracker.ietf.org/doc/html/rfc1123#page-55)
162+
Date/Time (Header) | Sun, 06 Nov 1994 08:49:37 GMT [RFC7231, Section 7.1.1.1](https://datatracker.ietf.org/doc/html/rfc7231#section-7.1.1.1)
164163
Date/Time (Query parameter) | YYYY-MM-DDTHH:mm:ss.sssZ (with at most 3 digits of fractional seconds) [RFC3339](https://datatracker.ietf.org/doc/html/rfc3339)
165164
Byte array | Base-64 encoded, max length
166165
Array | One of a) a comma-separated list of values (preferred), or b) separate `name=value` parameter instances for each value of the array
@@ -196,9 +195,9 @@ retry-after | Response | 180 (see [RFC 7231, Section 7.1.3](https://da
196195

197196
:white_check_mark: **DO** compare request header values using case-sensitivity if the header name requires it
198197

199-
:white_check_mark: **DO** accept and return date values in headers using the HTTP Date format as defined in [RFC 1123, Section 5.2.14](https://datatracker.ietf.org/doc/html/rfc1123#page-55), e.g. "Sun, 06 Nov 1994 08:49:37 GMT".
198+
:white_check_mark: **DO** accept date values in headers in HTTP-Date format and return date values in headers in the IMF-fixdate format as defined in [RFC7231, Section 7.1.1.1](https://datatracker.ietf.org/doc/html/rfc7231#section-7.1.1.1), e.g. "Sun, 06 Nov 1994 08:49:37 GMT".
200199

201-
Note: RFC 1123 defines the date format as a modification of the date format in [RFC 822, Section 5](https://datatracker.ietf.org/doc/html/rfc822#section-5) to support either a 2 or 4 digit year, and further recommends that a 4 digit year always be used.
200+
Note: The RFC 7321 IMF-fixdate format is a "fixed-length and single-zone subset" of the RFC 1123 / RFC 5822 format, which means: a) year must be four digits, b) the seconds component of time is required, and c) the timezone must be GMT.
202201

203202
:white_check_mark: **DO** create an opaque value that uniquely identifies the request and return this value in the `x-ms-request-id` response header.
204203

@@ -215,7 +214,7 @@ Your service should include the `x-ms-request-id` value in error logs so that us
215214

216215
### REpresentational State Transfer (REST)
217216
REST is an architectural style with broad reach that emphasizes scalability, generality, independent deployment, reduced latency via caching, and security. When applying REST to your API, you define your service’s resources as a collections of items.
218-
These are typically the nouns you use in the vocabulary of your service. Your service's [URLs](#URLS) determine the hierarchical path developers use to perform CRUD (create, read, update, and delete) operations on resources. Note, it's important to model resource state, not behavior.
217+
These are typically the nouns you use in the vocabulary of your service. Your service's [URLs](#uniform-resource-locators-urls) determine the hierarchical path developers use to perform CRUD (create, read, update, and delete) operations on resources. Note, it's important to model resource state, not behavior.
219218
There are patterns, later in these guidelines, that describe how to invoke behavior on your service. See [this article in the Azure Architecture Center](https://docs.microsoft.com/en-us/azure/architecture/best-practices/api-design) for a more detailed discussion of REST API design patterns.
220219

221220
When designing your service, it is important to optimize for the developer using your API.
@@ -444,23 +443,23 @@ The REST specification is used to model the state of a resource, and is primaril
444443

445444
:ballot_box_with_check: **YOU SHOULD** pattern your URL like this to perform an action on a resource
446445
**URL Pattern**
447-
```http
446+
```text
448447
https://.../<resource-collection>/<resource-id>:<action>?<input parameters>
449448
```
450449

451450
**Example**
452-
```http
451+
```text
453452
https://.../users/Bob:grant?access=read
454453
```
455454

456455
:ballot_box_with_check: **YOU SHOULD** pattern your URL like this to perform an action on a collection
457456
**URL Pattern**
458-
```http
457+
```text
459458
https://.../<resource-collection>:<action>?<input parameters>
460459
```
461460

462461
**Example**
463-
```http
462+
```text
464463
https://.../users:grant?access=read
465464
```
466465

@@ -542,7 +541,7 @@ The value of the `filter` option is an expression involving the fields of the re
542541

543542
Example: return all Products whose Price is less than $10.00
544543

545-
```http
544+
```text
546545
GET https://api.contoso.com/products?`filter`=price lt 10.00
547546
```
548547

@@ -566,7 +565,7 @@ not | Logical negation | not price le 3.5
566565
**Grouping Operators** | |
567566
( ) | Precedence grouping | (priority eq 1 or city eq 'Redmond') and price gt 100
568567

569-
:white_check_mark: **DO** respond with an error message as defined in the [Handling Errors](handling-errors) section if a client includes an operator in a `filter` expression that is not supported by the operation.
568+
:white_check_mark: **DO** respond with an error message as defined in the [Handling Errors](#handling-errors) section if a client includes an operator in a `filter` expression that is not supported by the operation.
570569

571570
:white_check_mark: **DO** use the following operator precedence for supported operators when evaluating `filter` expressions. Operators are listed by category in order of precedence from highest to lowest. Operators in the same category have equal precedence and should be evaluated left to right:
572571

@@ -590,31 +589,31 @@ The following examples illustrate the use and semantics of each of the logical o
590589

591590
Example: all products with a name equal to 'Milk'
592591

593-
```http
592+
```text
594593
GET https://api.contoso.com/products?`filter`=name eq 'Milk'
595594
```
596595

597596
Example: all products with a name not equal to 'Milk'
598597

599-
```http
598+
```text
600599
GET https://api.contoso.com/products?`filter`=name ne 'Milk'
601600
```
602601

603602
Example: all products with the name 'Milk' that also have a price less than 2.55:
604603

605-
```http
604+
```text
606605
GET https://api.contoso.com/products?`filter`=name eq 'Milk' and price lt 2.55
607606
```
608607

609608
Example: all products that either have the name 'Milk' or have a price less than 2.55:
610609

611-
```http
610+
```text
612611
GET https://api.contoso.com/products?`filter`=name eq 'Milk' or price lt 2.55
613612
```
614613

615614
Example: all products that have the name 'Milk' or 'Eggs' and have a price less than 2.55:
616615

617-
```http
616+
```text
618617
GET https://api.contoso.com/products?`filter`=(name eq 'Milk' or name eq 'Eggs') and price lt 2.55
619618
```
620619

@@ -639,17 +638,17 @@ Each expression in the `orderby` parameter value may include the suffix "asc" fo
639638
:white_check_mark: **DO** respond with an error message as defined in the [Handling Errors](#Handling-errors) section if the client requests sorting by a field that is not supported by the operation.
640639

641640
For example, to return all people sorted by name in ascending order:
642-
```http
641+
```text
643642
GET https://api.contoso.com/people?orderby=name
644643
```
645644

646645
For example, to return all people sorted by name in descending order and a secondary sort order of hireDate in ascending order.
647-
```http
646+
```text
648647
GET https://api.contoso.com/people?orderby=name desc,hireDate
649648
```
650649

651650
Sorting MUST compose with `filter`ing such that:
652-
```http
651+
```text
653652
GET https://api.contoso.com/people?`filter`=name eq 'david'&orderby=hireDate
654653
```
655654
will return all people whose name is David sorted in ascending order by hireDate.
@@ -691,7 +690,7 @@ Azure services need to change over time. However, when changing a service, there
691690

692691
: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.
693692

694-
```http
693+
```text
695694
PUT https://service.azure.com/users/Jeff?api-version=2021-06-04
696695
```
697696

0 commit comments

Comments
 (0)