Skip to content

Commit 9289c71

Browse files
committed
Merge pull request OAI#535 from jasonh-n-austin/guidelines_external_files
Refined guidelines for external file reuse
2 parents 33b6c58 + 5669bd4 commit 9289c71

File tree

1 file changed

+127
-59
lines changed

1 file changed

+127
-59
lines changed

guidelines/REUSE.md

Lines changed: 127 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,85 +1,140 @@
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
10+
* Models (_or Schema Objects in general_)
911
* Responses
10-
* Models (or Schema Objects in general)
12+
* Operations (_Operations can only be remote references_)
1113

1214
## Reuse strategy
13-
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.
1415

15-
The reuse technique is transparent between JSON or YAML and is lossless when converting between the two.
16+
When authoring API design documents, common object definitions can be utilized to avoid duplication. For example, imagine multiple path definitions that each share a common path parameter, or a common response structure. The OpenAPI specification allows reuse of common object definitions through the use of "references".
17+
18+
A reference is a construct in your API design document that indicates "the content for this portion of the document is defined elsewhere". To create a reference, at the location in your document where you want to reuse some other definition, create an object that has a `$ref` property whose value is a URI pointing to where the definition is (more on this in later sections).
19+
20+
OpenAPI's provides reference capabilities using the [JSON Reference](https://tools.ietf.org/html/draft-pbryan-zyp-json-ref-03) specification.
21+
22+
### JSON Example
23+
24+
``` js
25+
{
26+
// ...
27+
definitions: {
28+
Person: {
29+
type: 'object',
30+
properties: {
31+
friends: {
32+
type: 'array',
33+
items: {
34+
$ref: '#/definitions/Person'
35+
}
36+
}
37+
}
38+
}
39+
}
40+
}
41+
```
1642

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.
43+
### YAML Example
44+
45+
``` yaml
46+
# ...
47+
definitions:
48+
Person:
49+
type: object
50+
properties:
51+
friends:
52+
type: array
53+
items:
54+
$ref: '#/definitions/Person'
55+
```
1856
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).
57+
Note: YAML has a very similar feature, [YAML anchors](http://yaml.org/spec/1.2/spec.html#id2765878). Examples from this point will only be in JSON, using JSON References.
2058
2159
## Techniques
2260
2361
### Guidelines for Referencing
2462
25-
When referencing internally, the target references have designated locations:
63+
All references should follow the [JSON Reference](https://tools.ietf.org/html/draft-pbryan-zyp-json-ref-03) specification.
2664
27-
* Parameters -> `parameters`
28-
* Responses -> `responses`
29-
* Models (and general Schema Objects) -> `definitions`
65+
JSON Reference provides guidance on the resolution of references, notably:
3066
31-
Operations can only be referenced externally.
67+
> If the URI contained in the JSON Reference value is a relative URI,
68+
then the base URI resolution MUST be calculated according to
69+
[RFC3986], section 5.2. Resolution is performed relative to the
70+
referring document.
3271
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.
72+
Whether you reference definitions locally or remote, you can never override or change their definitions from the referring location. The definitions can only be used as-is.
3473
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:
74+
#### Local references
3675
37-
_Assuming file https://my.company.com/definitions/Model.json_
38-
```json
39-
{
40-
"description": "A simple model",
41-
"type": "object",
42-
"properties": {
43-
"id": {
44-
"type": "integer"
45-
}
46-
}
47-
}
76+
When referencing locally (within the current document), the target references should follow the conventions, as defined by the spec:
77+
78+
* Parameters -> `#/parameters`
79+
* Responses -> `#/responses`
80+
* Definitions (Models/Schema) -> `#/definitions`
81+
82+
An example of a local definition reference:
83+
84+
_Example from https://github.com/OAI/OpenAPI-Specification/blob/master/examples/v2.0/json/petstore.json_
85+
``` json
86+
// ...
87+
"200": {
88+
"description": "pet response",
89+
"schema": {
90+
"type": "array",
91+
"items": {
92+
"$ref": "#/definitions/Pet"
93+
}
94+
}
4895
```
4996

50-
The reference would be `https://my.company.com/definitions/Model.json`.
97+
#### Remote references
5198

52-
_Assuming file https://my.company.com/definitions/models.json_
53-
```json
54-
{
55-
"models": {
56-
"Model": {
57-
"description": "A simple model",
58-
"type": "object",
59-
"properties": {
60-
"id": {
61-
"type": "integer"
62-
}
63-
},
64-
"Tag": {
65-
"description": "A tag entity in the system",
66-
"type": "object",
67-
"properties": {
68-
"name": {
69-
"type": "string"
70-
}
71-
}
72-
}
73-
}
99+
##### Relative path
100+
101+
Files can be referred to in relative paths to the current document.
102+
103+
_Example from https://github.com/OAI/OpenAPI-Specification/tree/master/examples/v2.0/json/petstore-separate/spec/swagger.json_
104+
105+
``` json
106+
// ...
107+
"responses": {
108+
"default": {
109+
"description": "unexpected error",
110+
"schema": {
111+
"$ref": "../common/Error.json"
112+
}
113+
}
74114
}
75115
```
76116

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.
117+
Remote references may also reference properties within the relative remote file.
118+
119+
_Example from https://github.com/OAI/OpenAPI-Specification/tree/master/examples/v2.0/json/petstore-separate/spec/swagger.json_
120+
``` json
121+
// ...
122+
"parameters": [
123+
{
124+
"$ref": "parameters.json#/tagsParam"
125+
},
126+
{
127+
"$ref": "parameters.json#/limitsParam"
128+
}
129+
]
130+
```
78131

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

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:
133+
##### URL
134+
135+
Remote files can be hosted on an HTTP server (rather than the local file system).
136+
137+
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).
83138

84139
_Assuming file https://my.company.com/definitions/Model.json_
85140
```json
@@ -92,14 +147,14 @@ _Assuming file https://my.company.com/definitions/Model.json_
92147
"format": "int64"
93148
},
94149
"tag": {
95-
"description": "a complex, shared property. Note the absolute reference",
150+
"description": "A complex, shared property. Note the absolute reference",
96151
"$ref": "https://my.company.com/definitions/Tag.json"
97152
}
98153
}
99154
}
100155
```
101156

102-
For a single file, you can package the definitions in an object:
157+
Remote references may also reference properties within the remote file.
103158

104159
_Assuming file https://my.company.com/definitions/models.json_
105160
```json
@@ -133,8 +188,20 @@ _Assuming file https://my.company.com/definitions/models.json_
133188
```
134189

135190

191+
### Definitions
192+
193+
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.
194+
195+
Refer to [Guidelines for Referencing](#guidelines-for-referencing) for referencing strategies.
196+
197+
136198
### 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.
199+
200+
Similar to model schemas, you can create a repository of `parameters` to describe the common entities that appear throughout a set of systems.
201+
202+
Refer to [Guidelines for Referencing](#guidelines-for-referencing) for referencing strategies.
203+
204+
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.
138205

139206
_Assuming file https://my.company.com/parameters/parameters.json_
140207

@@ -205,7 +272,10 @@ To include these parameters, you would need to add them individually as such:
205272
```
206273

207274
### Operations
208-
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:
275+
276+
Again, Operations can be shared across files. Although the reusability of operations will be less than with Parameters and Definitions. For this example, we will share a common `health` resource so that all APIs can reference it:
277+
278+
Refer to [Guidelines for Referencing](#guidelines-for-referencing) for referencing strategies.
209279

210280
```json
211281
{
@@ -246,7 +316,8 @@ Which points to the reference in the `operations.json` file:
246316
Remember, you cannot override the definitions, but in this case, you can add additional operations on the same path level.
247317

248318
### Responses
249-
Just like the other objects, responses can be reused as well.
319+
320+
Refer to [Guidelines for Referencing](#guidelines-for-referencing) for referencing strategies.
250321

251322
Assume the file `responses.json`:
252323

@@ -299,6 +370,3 @@ You can refer to it from a response definition:
299370
}
300371
}
301372
```
302-
303-
### Constraints
304-
* Referenced objects must be to JSON structures. YAML reuse structures may be supported in a future version.

0 commit comments

Comments
 (0)