Skip to content

Commit fb78af3

Browse files
authored
Merge pull request #1704 from json-api-dotnet/openapi-inheritance
Add support for resource inheritance in OpenAPI
2 parents fcca17d + c9bb868 commit fb78af3

File tree

1,328 files changed

+125522
-18716
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,328 files changed

+125522
-18716
lines changed

Diff for: docs/docfx.json

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"files": [
2424
"api/**.yml",
2525
"api/index.md",
26+
"ext/openapi/index.md",
2627
"getting-started/**.md",
2728
"getting-started/**/toc.yml",
2829
"usage/**.md",

Diff for: docs/ext/openapi/index.md

+127
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
# JSON:API Extension for OpenAPI
2+
3+
This extension facilitates using OpenAPI client generators targeting JSON:API documents.
4+
5+
In JSON:API, a resource object contains the `type` member, which defines the structure of nested [attributes](https://jsonapi.org/format/#document-resource-object-attributes) and [relationships](https://jsonapi.org/format/#document-resource-object-relationships) objects.
6+
While OpenAPI supports such constraints using `allOf` inheritance with a discriminator property for the `data` member,
7+
it provides no way to express that the discriminator recursively applies to nested objects.
8+
9+
This extension addresses that limitation by defining additional discriminator properties to guide code generation tools.
10+
11+
## URI
12+
13+
This extension has the URI `https://www.jsonapi.net/ext/openapi`.
14+
Because code generators often choke on the double quotes in `Accept` and `Content-Type` HTTP header values, a relaxed form is also permitted: `openapi`.
15+
16+
For example, the following `Content-Type` header:
17+
18+
```http
19+
Content-Type: application/vnd.api+json; ext="https://www.jsonapi.net/ext/openapi"
20+
```
21+
22+
is equivalent to:
23+
24+
```http
25+
Content-Type: application/vnd.api+json; ext=openapi
26+
```
27+
28+
To avoid the need for double quotes when multiple extensions are used, the following relaxed form can be used:
29+
30+
```http
31+
Content-Type: application/vnd.api+json; ext=openapi; ext=atomic
32+
```
33+
34+
> [!NOTE]
35+
> The [base specification](https://jsonapi.org/format/#media-type-parameter-rules) *forbids* the use of multiple `ext` parameters
36+
> and *requires* that each extension name must be a URI.
37+
> This extension relaxes both constraints for practical reasons, to workaround bugs in client generators that produce broken code otherwise.
38+
39+
## Namespace
40+
41+
This extension uses the namespace `openapi`.
42+
43+
> [!NOTE]
44+
> JSON:API extensions can only introduce new document members using a reserved namespace as a prefix.
45+
46+
## Document Structure
47+
48+
A document that supports this extension MAY include any of the top-level members allowed by the base specification,
49+
including any members defined in the [Atomic Operations extension](https://jsonapi.org/ext/atomic/).
50+
51+
### Resource Objects
52+
53+
In addition to the members allowed by the base specification, the following member MAY be included
54+
in [attributes](https://jsonapi.org/format/#document-resource-object-attributes) and [relationships](https://jsonapi.org/format/#document-resource-object-relationships) objects:
55+
56+
* `openapi:discriminator` - A string that MUST be identical to the `type` member in the containing [resource object](https://jsonapi.org/format/#document-resource-objects).
57+
58+
Here's how an article (i.e. a resource of type "articles") might appear in a document:
59+
60+
```json
61+
{
62+
"data": {
63+
"type": "articles",
64+
"id": "1",
65+
"attributes": {
66+
"openapi:discriminator": "articles",
67+
"title": "Rails is Omakase"
68+
},
69+
"relationships": {
70+
"openapi:discriminator": "articles",
71+
"author": {
72+
"data": { "type": "people", "id": "9" }
73+
}
74+
}
75+
}
76+
}
77+
```
78+
79+
### Atomic Operations
80+
81+
In addition to the members allowed by the [Atomic Operations extension](https://jsonapi.org/ext/atomic/),
82+
the following member MAY be included in elements of an `atomic:operations` array:
83+
84+
* `openapi:discriminator` - A free-format string to facilitate generation of client code.
85+
86+
For example:
87+
88+
```http
89+
POST /operations HTTP/1.1
90+
Host: example.org
91+
Content-Type: application/vnd.api+json; ext="https://www.jsonapi.net/ext/openapi https://jsonapi.org/ext/atomic"
92+
Accept: application/vnd.api+json; ext="https://www.jsonapi.net/ext/openapi https://jsonapi.org/ext/atomic"
93+
94+
{
95+
"atomic:operations": [{
96+
"openapi:discriminator": "add-article",
97+
"op": "add",
98+
"data": {
99+
"type": "articles",
100+
"attributes": {
101+
"openapi:discriminator": "articles",
102+
"title": "JSON API paints my bikeshed!"
103+
}
104+
}
105+
}]
106+
}
107+
```
108+
109+
## Processing
110+
111+
A server MAY ignore the `openapi:discriminator` member in [attributes](https://jsonapi.org/format/#document-resource-object-attributes) and [relationships](https://jsonapi.org/format/#document-resource-object-relationships) objects from incoming requests.
112+
A server SHOULD ignore the `openapi:discriminator` member in elements of an `atomic:operations` array.
113+
114+
A server MUST include the `openapi:discriminator` member in [attributes](https://jsonapi.org/format/#document-resource-object-attributes) and [relationships](https://jsonapi.org/format/#document-resource-object-relationships) objects in outgoing responses.
115+
The member value MUST be the same as the `type` member value of the containing resource object.
116+
117+
A client MAY include the `openapi:discriminator` member in [attributes](https://jsonapi.org/format/#document-resource-object-attributes) and [relationships](https://jsonapi.org/format/#document-resource-object-relationships) objects in outgoing requests.
118+
The member value MUST be the same as the `type` member value of the containing resource object.
119+
120+
A client MAY include the `openapi:discriminator` member in elements of an `atomic:operations` array.
121+
122+
### Processing Errors
123+
124+
A server SHOULD validate that the value of the `openapi:discriminator` member in
125+
[attributes](https://jsonapi.org/format/#document-resource-object-attributes) and [relationships](https://jsonapi.org/format/#document-resource-object-relationships) objects
126+
is identical to the `type` member in the containing resource object. When validation fails, the server MUST respond with a `409 Conflict`
127+
and SHOULD include a document with a top-level `errors` member that contains an error object.

0 commit comments

Comments
 (0)