@@ -64,15 +64,23 @@ If a request specifies the `Content-Type` header with the JSON:API media type,
64
64
servers ** MUST** respond with a ` 415 Unsupported Media Type ` status code if that
65
65
media type contains any media type parameters other than ` ext ` or ` profile ` .
66
66
67
+ > Note: Older JSON: API servers that do not support the ` ext ` or ` profile ` media
68
+ type parameters will respond with a ` 415 Unsupported Media Type ` client error
69
+ status if the ` ext ` or ` profile ` media type parameter is present.
70
+
67
71
If a request's ` Accept ` header contains an instance of the JSON: API media type,
68
72
servers ** MUST** respond with a ` 406 Not Acceptable ` status code if all
69
73
instances of that media type are modified with a media type parameter other
70
- than ` ext ` or ` profile ` .
74
+ than ` ext ` or ` profile ` . If every instance of that media type is modified by the
75
+ ` ext ` parameter and each contains at least one unsupported extension URI, the
76
+ server ** MUST** also respond with a ` 406 Not Acceptable ` .
71
77
72
- If a request's ` Accept ` header contains an instance of the JSON: API media type,
73
- servers ** MUST** respond with a ` 406 Not Acceptable ` status code if every
74
- instance of that media type is modified by the ` ext ` parameter and each
75
- contains at least one unsupported extension URI.
78
+ Servers that support profiles ** SHOULD** specify the ` Vary ` header with
79
+ ` Accept ` as one of its values. This applies to responses with and without any
80
+ profiles applied.
81
+
82
+ > Note: Some HTTP intermediaries (e.g. CDNs) may ignore the ` Vary ` header
83
+ unless specifically configured to respect it.
76
84
77
85
## <a href =" #document-structure " id =" document-structure " class =" headerlink " ></a > Document Structure
78
86
@@ -1965,40 +1973,6 @@ identification:
1965
1973
However, to aid human understanding, visiting a profile's URI ** SHOULD** return
1966
1974
documentation of the profile.
1967
1975
1968
- The following example profile reserves a ` timestamps ` member in the ` meta `
1969
- object of every resource object:
1970
-
1971
- <a id =" profiles-timestamp-profile " ></a >
1972
- ``` text
1973
- # Timestamps profile
1974
-
1975
- ## Introduction
1976
-
1977
- This page specifies a profile for the `application/vnd.api+json` media type,
1978
- as described in the [JSON:API specification](http://jsonapi.org/format/).
1979
-
1980
- This profile allows every resource in a JSON:API document to represent
1981
- significant timestamps in a consistent way.
1982
-
1983
- ## Document Structure
1984
-
1985
- Every resource object **MAY** include a `timestamps` member in its associated
1986
- `meta` object. If this member is present, its value **MUST** be an object that
1987
- **MAY** contain any of the following members:
1988
-
1989
- * `created`
1990
- * `updated`
1991
-
1992
- The value of each member **MUST** comply with the variant of ISO 8601 used by
1993
- JavaScript's `JSON.stringify` method to format Javascript `Date` objects.
1994
-
1995
- ## Keywords
1996
-
1997
- This profile defines the following keywords:
1998
-
1999
- * `timestamps`
2000
- ```
2001
-
2002
1976
### <a href =" #profile-media-type-parameter " id =" profile-media-type-parameter " class =" headerlink " ></a > ` profile ` Media Type Parameter
2003
1977
2004
1978
The ` profile ` media type parameter is used to describe the application of
@@ -2028,9 +2002,6 @@ Servers **MAY** respond with a subset of the requested profiles applied or none
2028
2002
of the requested profiles applied. Additionally, servers ** MAY** respond with
2029
2003
unrequested profiles applied.
2030
2004
2031
- The recipient of a document to which an unknown profile has been applied
2032
- ** MUST** ignore any document members that it does not understand.
2033
-
2034
2005
#### <a href =" #profiles-sending " id =" profiles-sending " class =" headerlink " ></a > Sending Profiled Documents
2035
2006
2036
2007
Clients and servers ** MUST** include the ` profile ` media type parameter in
@@ -2042,285 +2013,6 @@ include a [top-level][top level] [`links` object][links] with a `profile` key,
2042
2013
and that ` profile ` key ** MUST** include a [ link] to the URI of each profile
2043
2014
that has been applied.
2044
2015
2045
- When an older JSON: API server that doesn't support the ` profile ` media type
2046
- parameter receives a document with one or more profiles, it will respond with a
2047
- ` 415 Unsupported Media Type ` error.
2048
-
2049
- After attempting to rule out other possible causes of this error, a client that
2050
- receives a ` 415 Unsupported Media Type ` ** SHOULD** remove the profiles it has
2051
- applied to the document and retry its request without the ` profile ` media type
2052
- parameter. If this resolves the error, the client ** SHOULD NOT** attempt to
2053
- apply profiles in subsequent interactions with the same API.
2054
-
2055
- > The most likely other causes of a 415 error are that the server doesn't
2056
- support JSON: API at all.
2057
-
2058
- Servers that support profiles ** SHOULD** specify the ` Vary ` header with
2059
- ` Accept ` as one of its header names to ensure that the server's responses can
2060
- be cached without disrupting subsequent content negotiations. This applies to
2061
- responses with and without any profiles applied.
2062
-
2063
- > Note: Some HTTP intermediaries (e.g. CDNs) may ignore the ` Vary ` header
2064
- > unless specifically configured to respect it.
2065
-
2066
- ### <a href =" #profile-keywords " id =" profile-keywords " class =" headerlink " ></a > Profile Keywords
2067
-
2068
- A profile ** SHOULD** explicitly declare "keywords" for any elements that it
2069
- introduces to the document structure. If a profile does not explicitly declare a
2070
- keyword for an element, then the name of the element itself (i.e., its key in
2071
- the document) is considered to be its keyword. All profile keywords ** MUST**
2072
- meet this specification's requirements for [ member names] .
2073
-
2074
- In other words, if a profile introduces an object-valued document member, that
2075
- member is an element, but any keys in it are not themselves elements. Likewise,
2076
- if the profile defines an array-valued element, the keys in nested objects
2077
- within that array are not elements.
2078
-
2079
- The following example profile defines a single keyword, ` version ` :
2080
-
2081
- ``` text
2082
- # Resource versioning profile
2083
-
2084
- ## Introduction
2085
-
2086
- This page specifies a profile for the `application/vnd.api+json` media type,
2087
- as described in the [JSON:API specification](http://jsonapi.org/format/).
2088
-
2089
- This profile ensures that every resource represented in a JSON:API document
2090
- includes a version.
2091
-
2092
- ## Document Structure
2093
-
2094
- Every resource **MUST** include a `meta` object containing a `version` member.
2095
- The value of this member **MUST** be a string that represents a unique version
2096
- for that resource.
2097
-
2098
- ## Keywords
2099
-
2100
- This profile defines the following keywords:
2101
-
2102
- * `version`
2103
- ```
2104
-
2105
- This profile might be applied as follows:
2106
-
2107
- ``` json
2108
- {
2109
- "data" : {
2110
- "type" : " contacts" ,
2111
- "id" : " 345" ,
2112
- "meta" : {
2113
- "version" : " 2018-04-14-879976658"
2114
- },
2115
- "attributes" : {
2116
- "name" : " Ethan"
2117
- }
2118
- },
2119
- "links" : {
2120
- "profile" : [" http://example.com/profiles/resource-versioning" ]
2121
- }
2122
- }
2123
- ```
2124
-
2125
-
2126
- ### <a href =" #profiles-processing " id =" profiles-processing " class =" headerlink " ></a > Processing Profiled Documents/Requests
2127
-
2128
- When a profile is applied to a request and/or document, the value used for each
2129
- of the profile's document members or query parameters is said to be "a
2130
- recognized value" if that value, including all parts of it, has a legal, defined
2131
- meaning * according to the latest revision of the profile that the application is
2132
- aware of* .
2133
-
2134
- > Note: The set of recognized values is also/more technically known as the
2135
- > [ defined text set] ( http://www.w3.org/2001/tag/doc/versioning-compatibility-strategies#terminology ) .
2136
-
2137
- For example, the hypothetical [ timestamps profile] specifies the ` timestamps `
2138
- element, and the meaning for two keys within it -- ` created ` and ` updated ` .
2139
- Therefore, in the following use of the profile, the value for the timestamps
2140
- element would be a recognized value:
2141
-
2142
- ``` json
2143
- {
2144
- "type" : " contacts" ,
2145
- "id" : " 345" ,
2146
- "meta" : {
2147
- "timestamps" : { "created" : " 2018-08-29T18:38:17.567Z" }
2148
- }
2149
- //...
2150
- }
2151
- ```
2152
-
2153
- However, in the following case, the value for ` timestamps ` is * not* a recognized
2154
- value because one of the keys in it, ` createdUnixEpoch ` , doesn't have a meaning
2155
- assigned to it in the timestamps profile:
2156
-
2157
- ``` json
2158
- {
2159
- "type" : " contacts" ,
2160
- "id" : " 345" ,
2161
- "meta" : {
2162
- "timestamps" : {
2163
- "createdUnixEpoch" : 1535567910201 ,
2164
- "created" : " 2018-08-29T18:38:17.567Z"
2165
- }
2166
- }
2167
- //...
2168
- }
2169
- ```
2170
-
2171
- Likewise, if a profile defines an element and enumerates ` true ` and ` false `
2172
- as legal values with a specific meaning, then a string appearing as that
2173
- element's value would be an unrecognized value.
2174
-
2175
- > Note: unrecognized values are not necessarily invalid or erroneous values.
2176
- > For example, the timestamps profile might be revised later to actually define
2177
- > a "createdUnixEpoch" key. This key would be unrecognized by all applications
2178
- > that existed at the time it was defined, but not by ones created/deployed later.
2179
-
2180
- Each profile ** MAY** define its own rules for how applications should proceed
2181
- when encountering unrecognized values.
2182
-
2183
- If a profile does not define its own rules for handling unrecognized values,
2184
- the following rule applies by default:
2185
-
2186
- 1 . If the value of a profile-defined query parameter is unrecognized, the
2187
- server ** MUST** fail the request and respond with a ` 400 Bad Request ` and
2188
- an [ error object] [ error objects ] indicating the problematic parameter.
2189
-
2190
- 2 . Otherwise, if the unrecognized value is a JSON object in the
2191
- request/response document, and the only thing that makes it unrecognized
2192
- is that it contains one or more keys that have no meaning assigned to them
2193
- (in the latest revision of the profile that the application is aware of),
2194
- then the application ** MUST** simply ignore those unknown keys and
2195
- continue processing the profile.
2196
-
2197
- 3 . In all other cases, the application ** MUST** assume that the profile has
2198
- been applied erroneously and ** MUST** totally ignore the profile (i.e.,
2199
- process the request as if the profile were not there).
2200
-
2201
- In the case of our example [ timestamps profile] , it does not define its own
2202
- rules, so the above defaults would apply.
2203
-
2204
- Under the second of these default rules, the unrecognized value we saw
2205
- above (with the ` createdUnixEpoch ` key) would be processed as though the
2206
- ` createdUnixEpoch ` key simply weren't present, and the application would still
2207
- be able to use the data in the ` created ` key.
2208
-
2209
- However, if the user instead provided the following value, the whole timestamps
2210
- profile would need to be ignored:
2211
-
2212
- ``` json
2213
- {
2214
- //...
2215
- "timestamps" : {
2216
- "updated" : " Wed Aug 29 2018 15:00:05 GMT-0400" ,
2217
- "created" : " 2018-08-29T18:38:17.567Z"
2218
- }
2219
- }
2220
- ```
2221
-
2222
- Ignoring the profile in this case is required by the third default rule,
2223
- because the value for the ` updated ` key is not recognized under the profile's
2224
- requirement that the ` updated ` key hold a string of the form produced by
2225
- ` JSON.stringify ` .
2226
-
2227
- ### <a href =" #profiles-authoring " id =" profiles-authoring " class =" headerlink " ></a > Authoring Profiles
2228
-
2229
- A profile ** MAY** assign meaning to elements of the document structure whose use
2230
- is left up to each implementation, such as resource fields or members of ` meta `
2231
- objects. A profile ** MUST NOT** define/assign a meaning to document members
2232
- in areas of the document reserved for future use by the JSON: API specification.
2233
-
2234
- For example, it would be illegal for a profile to define a new key in a
2235
- document's [ top-level] [ top level ] object, or in a [ links object] [ links ] , as
2236
- JSON API implementations are not allowed to add custom keys in those areas.
2237
-
2238
- Likewise, a profile ** MAY** assign a meaning to query parameters or parameter
2239
- values whose details are left up to each implementation, such as ` filter ` and
2240
- all parameters that contain a non a-z character. However, profiles ** MUST NOT**
2241
- assign a meaning to query parameters that [ are reserved] ( #query-parameters ) .
2242
-
2243
- The meaning of an element or query parameter defined by a profile ** MUST NOT**
2244
- vary based on the presence or absence of other profiles.
2245
-
2246
- The scope of a profile ** MUST** be clearly delineated. The elements and query
2247
- parameters specified by a profile, and their meanings, ** MUST NOT** change over
2248
- time or else the profile ** MUST** be considered a new profile with a new URI.
2249
-
2250
- > Note: When a profile changes its URI, a huge amount of interoperability is lost.
2251
- > Users that reference the new URI will not have their messages understood by
2252
- > implementations still aware only of the old URI, and vice-versa. Accordingly,
2253
- > it's important to design your profile so that it can evolve without its URI
2254
- > needing to change. See [ "Revising a Profile"] ( #profiles-updating ) for details.
2255
-
2256
- Finally, a profile ** MUST NOT** :
2257
-
2258
- 1 . assume that, if it is supported, then other specific profiles will be
2259
- supported as well.
2260
-
2261
- 2 . define fixed endpoints, HTTP headers, or header values.
2262
-
2263
- 3 . alter the JSON structure of any concept defined in this specification,
2264
- including to allow a superset of JSON structures.
2265
-
2266
-
2267
- > If you create your own profile, you are ** strongly encouraged to [ register] ( /extensions/#profile-creation )
2268
- > it** with the JSON API [ profile registry] ( /extensions/ ) , so that others can
2269
- > find and reuse it.
2270
-
2271
- #### <a href =" #profiles-updating " id =" profiles-updating " class =" headerlink " ></a > Revising a Profile
2272
-
2273
- Profiles ** MAY** be revised over time, e.g., to add new capabilities. However,
2274
- any such changes ** MUST** be [ backwards and forwards compatible] ( http://www.w3.org/2001/tag/doc/versioning-compatibility-strategies#terminology )
2275
- ("compatible evolution"), in order to not break existing users of the profile.
2276
-
2277
- For example, the hypothetical [ timestamps profile] * could not* introduce a new,
2278
- required ` deleted ` member within the ` timestamps ` object, as that would be
2279
- incompatible with existing deployments of the profile, which would not include
2280
- this new member.
2281
-
2282
- The timestamps profile also * could not* evolve to define a new element as a
2283
- sibling of the ` timestamps ` key, as that would be incompatible with the rule
2284
- that "The elements... specified by a profile... ** MUST NOT** change over time."
2285
-
2286
- > The practical issue with adding a sibling element is that another profile
2287
- > in use on the document might already define a sibling element of the same
2288
- > name.
2289
-
2290
- However, the timestamps profile could evolve to allow other optional members,
2291
- such as ` deleted ` , in the ` timestamps ` object. This is possible because the
2292
- ` timestamps ` object is already a reserved element of the profile, and the profile
2293
- is subject to the default rule that new (previously unrecognized) keys will
2294
- simply be ignored by existing applications.
2295
-
2296
- ##### <a href =" #profiles-design-for-evolution " id =" profiles-design-for-evolution " class =" headerlink " ></a > Designing Profiles to Evolve Over Time
2297
-
2298
- Fundamentally, for a profile to be able to change in a compatible way over time,
2299
- it must define -- from the beginning -- a rule describing how an application
2300
- that is only familiar with the original version of the profile should process
2301
- documents/requests that use features from an updated version of the profile.
2302
-
2303
- One major approach is to simply have applications ignore (at least some types of)
2304
- unrecognized data. This allows the profile to define new, optional features;
2305
- old applications will continue to work, but simply won't process/"see" these new
2306
- capabilities.
2307
-
2308
- This is essentially the strategy that JSON: API itself uses when it says that:
2309
-
2310
- > Client and server implementations ** MUST** ignore members not recognized by
2311
- > this specification.
2312
-
2313
- Other protocols use analogous strategies. E.g., in HTTP, unknown headers are
2314
- simply ignored; they don't crash the processing of the request/response.
2315
-
2316
- As a profile author, you may define your own rules for how applications should
2317
- process uses of the profile that contain unrecognized data, or you may simply
2318
- allow the default rules described in the [ "Processing Profiled Documents/Requests"] ( #profiles-processing )
2319
- to take effect.
2320
-
2321
- If you choose to use the default rules, you ** SHOULD** reserve an object-valued
2322
- element anywhere you expect to potentially add new features over time.
2323
-
2324
2016
## <a href =" #errors " id =" errors " class =" headerlink " ></a > Errors
2325
2017
2326
2018
### <a href =" #errors-processing " id =" errors-processing " class =" headerlink " ></a > Processing Errors
@@ -2434,8 +2126,6 @@ request as equivalent to one in which the square brackets were percent-encoded.
2434
2126
[ link parameters ] : #document-links-link-parameters
2435
2127
[ extensions ] : #extensions
2436
2128
[ profiles ] : #profiles
2437
- [ timestamps profile ] : #profiles-timestamp-profile
2438
- [ profile keywords ] : #profile-keywords
2439
2129
[ error details ] : #errors
2440
2130
[ error object ] : #error-objects
2441
2131
[ error objects ] : #errror-objects
0 commit comments