Skip to content

Commit 98d6d44

Browse files
committed
Refined guidelines for external file reuse
1 parent 52972a9 commit 98d6d44

File tree

1 file changed

+111
-19
lines changed

1 file changed

+111
-19
lines changed

guidelines/REUSE.md

Lines changed: 111 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,65 @@
11
# Reuse Philosophy
2+
23
We encourage reuse and patterns through references.
34

45
## What is reusable
6+
57
The following types are reusable, as defined by the spec:
68

7-
* Operations
89
* Parameters
9-
* Responses
1010
* Models (or Schema Objects in general)
11+
* Responses
12+
* Operations (_Operations can only be referenced externally_)
1113

1214
## Reuse strategy
15+
1316
When reusing components in an API design, a pointer is created from the definition to target design. The references are maintained in the structure, and can be updated by modifying the source definitions. This is different from a "copy on design" approach where references are injected into the design itself.
1417

1518
The reuse technique is transparent between JSON or YAML and is lossless when converting between the two.
1619

17-
YAML anchors are technically allowed but break the general reuse strategy in Swagger, since anchors are "injected" into a single document. They are not recommended.
20+
YAML anchors are technically allowed but break the general reuse strategy in OpenAPI Specification, since anchors are "injected" into a single document. They are not recommended.
1821

19-
Referenes can be made either inside the Swagger definition file or to external files. References are done using [JSON Reference](http://tools.ietf.org/html/draft-pbryan-zyp-json-ref-03).
22+
Referenes can be made either internal to the OpenApi Specification file or to external files.
2023

2124
## Techniques
2225

2326
### Guidelines for Referencing
2427

28+
Whether you reference definitions internally or externally, you can never override or change their definitions from the referring location. The definitions can only be used as-is.
29+
30+
#### Internal references
31+
2532
When referencing internally, the target references have designated locations:
2633

27-
* Parameters -> `parameters`
28-
* Responses -> `responses`
29-
* Models (and general Schema Objects) -> `definitions`
34+
* Parameters -> `#/parameters`
35+
* Responses -> `#/responses`
36+
* Models (and general Schema Objects) -> `#/definitions`
37+
38+
All references are canonical and must be a qualified [JSON Pointer, per RFC6901](http://tools.ietf.org/html/rfc6901). For example, simply referencing a model `Pet` is not allowed, even if there are no other definitions of it in the file.
39+
40+
_Example from https://github.com/OAI/OpenAPI-Specification/blob/master/examples/v2.0/json/petstore.json_
41+
``` json
42+
"200": {
43+
"description": "pet response",
44+
"schema": {
45+
"type": "array",
46+
"items": {
47+
"$ref": "#/definitions/Pet"
48+
}
49+
}
50+
```
51+
52+
#### External references
3053

31-
Operations can only be referenced externally.
54+
If your referenced file contains only one root-level definition, you can refer to the file directly.
3255

33-
An example for an internal reference - `#/definitions/MyModel`. All references are canonical and must be a qualified [JSON Pointer](http://tools.ietf.org/html/rfc6901). For example, simply referencing `MyModel` is not allowed, even if there are no other definitions of it in the file.
56+
To reference the example below:
3457

35-
When referencing externally, use a valid URI as the reference value. If your referenced file contains only one definition that should be used, you can refer to the file directly. For example:
58+
`"$ref": "definitions/Model.json""`
59+
60+
or
61+
62+
`"$ref": "https://my.company.com/definitions/Model.json"`.
3663

3764
_Assuming file https://my.company.com/definitions/Model.json_
3865
```json
@@ -47,7 +74,16 @@ _Assuming file https://my.company.com/definitions/Model.json_
4774
}
4875
```
4976

50-
The reference would be `https://my.company.com/definitions/Model.json`.
77+
To reference `Model` in the example below:
78+
79+
_Note this approach potentially combines URL, JSON Reference, and JSON Pointer_
80+
81+
`"$ref": "definitions/models.json#/models/Model"`
82+
83+
or
84+
85+
`"$ref": "https://my.company.com/definitions/models.json#/models/Model"`
86+
5187

5288
_Assuming file https://my.company.com/definitions/models.json_
5389
```json
@@ -74,12 +110,52 @@ _Assuming file https://my.company.com/definitions/models.json_
74110
}
75111
```
76112

77-
The reference to the `Model` model would be `https://my.company.com/definitions/models.json#/models/Model`. Make sure you include the full path to the model itself, including its containers if needed.
113+
#### External by relative reference
78114

79-
Whether you reference definitions internally or externally, you can never override or change their definitions from the referring location. The definitions can only be used as-is.
115+
All external relative references should follow the [JSON Reference](https://tools.ietf.org/html/draft-pbryan-zyp-json-ref-03) specification.
80116

81-
### Definitions
82-
Reuse schema definitions by creating a repository of definitions. This is done by simply hosting a file or set of files for commonly used definitions across a company or organization. In the case of multiple files, the models can be referenced directly as such:
117+
Per the JSON Reference spec:
118+
119+
> If the URI contained in the JSON Reference value is a relative URI,
120+
then the base URI resolution MUST be calculated according to
121+
[RFC3986], section 5.2. Resolution is performed relative to the
122+
referring document.
123+
124+
_Example from https://github.com/OAI/OpenAPI-Specification/tree/master/examples/v2.0/json/petstore-separate/spec/swagger.json_
125+
126+
``` json
127+
"responses": {
128+
"default": {
129+
"description": "unexpected error",
130+
"schema": {
131+
"$ref": "../common/Error.json"
132+
}
133+
}
134+
}
135+
```
136+
137+
External references may also utilize [JSON Pointer](http://tools.ietf.org/html/rfc6901) to reference properties within the relative external file.
138+
139+
_Example from https://github.com/OAI/OpenAPI-Specification/tree/master/examples/v2.0/json/petstore-separate/spec/swagger.json_
140+
``` json
141+
"parameters": [
142+
{
143+
"$ref": "parameters.json#/tagsParam"
144+
},
145+
{
146+
"$ref": "parameters.json#/limitsParam"
147+
}
148+
]
149+
```
150+
151+
152+
#### External by URL
153+
154+
External files can be hosted on an HTTP server (rather than the local file system).
155+
156+
One risk of this approach is that environment specific issues could arise if DNS is not taken into account (as the reference can only contain one hostname).
157+
158+
Resolution of URLs should follow [RFC3986](https://tools.ietf.org/html/rfc3986).
83159

84160
_Assuming file https://my.company.com/definitions/Model.json_
85161
```json
@@ -92,14 +168,14 @@ _Assuming file https://my.company.com/definitions/Model.json_
92168
"format": "int64"
93169
},
94170
"tag": {
95-
"description": "a complex, shared property. Note the absolute reference",
171+
"description": "A complex, shared property. Note the absolute reference",
96172
"$ref": "https://my.company.com/definitions/Tag.json"
97173
}
98174
}
99175
}
100176
```
101177

102-
For a single file, you can package the definitions in an object:
178+
External references may also utilize a URL + JSON Pointer to reference properties within the external file.
103179

104180
_Assuming file https://my.company.com/definitions/models.json_
105181
```json
@@ -133,8 +209,20 @@ _Assuming file https://my.company.com/definitions/models.json_
133209
```
134210

135211

212+
### Definitions
213+
214+
Reuse schema definitions by creating a repository of definitions. This is done by simply hosting a file or set of files for commonly used definitions across a company or organization.
215+
216+
Refer to [External references](#external-references) for referencing strategies.
217+
218+
136219
### Parameters
137-
Similar to model schemas, you can create a repository of `parameters` to describe the common entities that appear throughout a set of systems. Using the same technique as above, you can host on either a single or multiple files. For simplicity, the example below assumes a single file.
220+
221+
Similar to model schemas, you can create a repository of `parameters` to describe the common entities that appear throughout a set of systems.
222+
223+
Refer to [External references](#external-references) for referencing strategies.
224+
225+
Using the same technique as above, you can host on either a single or multiple files. For simplicity, the example below assumes a single file.
138226

139227
_Assuming file https://my.company.com/parameters/parameters.json_
140228

@@ -205,8 +293,11 @@ To include these parameters, you would need to add them individually as such:
205293
```
206294

207295
### Operations
296+
208297
Again, Operations can be shared across files. Although the reusability of operations will be less than with Parameters and models. For this example, we will share a common `health` resource so that all APIs can reference it:
209298

299+
Refer to [External references](#external-references) for additional referencing strategies.
300+
210301
```json
211302
{
212303
"/health": {
@@ -246,7 +337,8 @@ Which points to the reference in the `operations.json` file:
246337
Remember, you cannot override the definitions, but in this case, you can add additional operations on the same path level.
247338

248339
### Responses
249-
Just like the other objects, responses can be reused as well.
340+
341+
Refer to [External references](#external-references) for additional referencing strategies.
250342

251343
Assume the file `responses.json`:
252344

0 commit comments

Comments
 (0)