Skip to content

Commit f845a33

Browse files
dgebgabesullice
andauthored
Simplify profiles for v1.1 (json-api#1456)
* Move profile language to the extensions page and reduce profile scope * Remove language about ignoring document members and resending unprofiled documents. - Ignoring document members is not necessary for profiles since they can no longer add new members to reserved areas of the specification. - Clients should not need to resend unprofiled documents because servers should be able to ignore profiles. * Move the header language to server responsibilities * Move note about older servers and the profile media type parameter to client responsibilities. * Restore sentence about resolving a profile URI to documentation. * Restore the extensions page to its original form. * Move the note about older servers and the profile media type parameter. Co-authored-by: Gabe Sullice <gabriel@sullice.com>
1 parent a20e262 commit f845a33

File tree

2 files changed

+43
-324
lines changed

2 files changed

+43
-324
lines changed

_format/1.1/index.md

Lines changed: 13 additions & 323 deletions
Original file line numberDiff line numberDiff line change
@@ -64,15 +64,23 @@ If a request specifies the `Content-Type` header with the JSON:API media type,
6464
servers **MUST** respond with a `415 Unsupported Media Type` status code if that
6565
media type contains any media type parameters other than `ext` or `profile`.
6666

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+
6771
If a request's `Accept` header contains an instance of the JSON:API media type,
6872
servers **MUST** respond with a `406 Not Acceptable` status code if all
6973
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`.
7177

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.
7684

7785
## <a href="#document-structure" id="document-structure" class="headerlink"></a> Document Structure
7886

@@ -1965,40 +1973,6 @@ identification:
19651973
However, to aid human understanding, visiting a profile's URI **SHOULD** return
19661974
documentation of the profile.
19671975

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-
20021976
### <a href="#profile-media-type-parameter" id="profile-media-type-parameter" class="headerlink"></a> `profile` Media Type Parameter
20031977

20041978
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
20282002
of the requested profiles applied. Additionally, servers **MAY** respond with
20292003
unrequested profiles applied.
20302004

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-
20342005
#### <a href="#profiles-sending" id="profiles-sending" class="headerlink"></a> Sending Profiled Documents
20352006

20362007
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,
20422013
and that `profile` key **MUST** include a [link] to the URI of each profile
20432014
that has been applied.
20442015

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-
23242016
## <a href="#errors" id="errors" class="headerlink"></a> Errors
23252017

23262018
### <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.
24342126
[link parameters]: #document-links-link-parameters
24352127
[extensions]: #extensions
24362128
[profiles]: #profiles
2437-
[timestamps profile]: #profiles-timestamp-profile
2438-
[profile keywords]: #profile-keywords
24392129
[error details]: #errors
24402130
[error object]: #error-objects
24412131
[error objects]: #errror-objects

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy