). It supports:
29 |
30 | * sending an SMS (an outgoing API call, currently supported)
31 | * receiving a delivery receipt when you just sent an SMS (callback, currently supported)
32 | * receiving an incoming SMS (webhook, not currently supported)
33 |
34 | The docs have an `x-webhooks` top-level element (we use [our own docs renderer](https://github.com/Nexmo/nexmo-oas-renderer)) and then a meaningless URL fieldname before the path item object that descrives the webhook.
35 |
36 | On one of the other Nexmo APIs, we simply documented our webhooks in a markdown file separate from our API even though the two directions are very closely linked (see [Voice API webhook reference](https://developer.nexmo.com/voice/voice-api/webhook-reference) ).
37 |
38 | Neither solution is great. I'm aware of other organisations (Ebay, GitHub) who also offer webhooks as part of their API platform who have run into the same problems when looking to adopt OpenAPI. The existing approach for callbacks, which allow a Path Item Object to be described in another location, could be adapted to also describe webhooks.
39 |
40 | ## Proposed solution
41 |
42 | Allow a top-level `webhooks` element, with named entries inside it, each containing a Path Item Object. No other new fields or changes would be needed, since this already works brilliantly for `callbacks` within a path item. The only difference here is that there's no existing path item for the callback/webhook to belong to, and the URL is usually set somewhere else by the user (and there's no request context for an expression to be evaluated).
43 |
44 | This solution builds on the existing proven approach for callbacks, but detaches them from the following-a-previous-API-call constraint.
45 |
46 | To borrow the Nexmo SMS API example from above (because it's simple, I can add more examples as needed), the spec for the incoming webhook that occurs because a message has arrived might look like this:
47 |
48 | ```
49 | webhooks:
50 | inbound-sms:
51 | post:
52 | summary: Inbound SMS to your Nexmo number
53 | operationId: inbound-sms
54 | description: |
55 | If you rent one or more virtual numbers from Nexmo, inbound messages to that number are sent to your [webhook endpoint](https://developer.nexmo.com/concepts/guides/webhooks).
56 | requestBody:
57 | required: true
58 | content:
59 | application/json:
60 | schema:
61 | type: object
62 | required:
63 | - msisdn
64 | - to
65 | - messageid
66 | - text
67 | - type
68 | - keyword
69 | - message-timestamp
70 | properties:
71 | msisdn:
72 | type: string
73 | description: the phone number that this inbound message was sent from. numbers are specified in e.164 format.
74 | example: '447700900001'
75 | to:
76 | type: string
77 | description: the phone number the message was sent to. **this is your virtual number**. numbers are specified in e.164 format.
78 | example: '447700900000'
79 | messageid:
80 | type: string
81 | description: the id of the message
82 | example: 0a0000000123abcd1
83 | text:
84 | type: string
85 | description: The message body for this inbound message.
86 | example: Hello world
87 | type:
88 | type: string
89 | description: |
90 | Possible values are:
91 |
92 | - `text` - standard text.
93 | - `unicode` - URLencoded unicode . This is valid for standard GSM, Arabic, Chinese, double-encoded characters and so on.
94 | - `binary` - a binary message.
95 | example: 'text'
96 | keyword:
97 | type: string
98 | description: The first word in the message body. This is typically used with short codes.
99 | example: Hello
100 | message-timestamp:
101 | description: The time when Nexmo started to push this Delivery Receipt to your webhook endpoint.
102 | type: string
103 | example: 2020-01-01 12:00:00
104 | responses:
105 | '200':
106 | description: |
107 | Your server returns this code if it accepts the callback. Note that
108 | Nexmo will retry messages that are not successfully acknowledged.
109 | ```
110 |
111 | ## Detailed design
112 |
113 | ### Add the `webhooks` top-level element to the list
114 |
115 | **Existing Spec:**
116 |
117 | ```
118 | #### OpenAPI Object
119 |
120 | This is the root document object of the [OpenAPI document](#oasDocument).
121 |
122 | ##### Fixed Fields
123 |
124 | Field Name | Type | Description
125 | ---|:---:|---
126 | openapi | `string` | **REQUIRED**. This string MUST be the [semantic version number](https://semver.org/spec/v2.0.0.html) of the [OpenAPI Specification version](#versions) that the OpenAPI document uses. The `openapi` field SHOULD be used by tooling specifications and clients to interpret the OpenAPI document. This is *not* related to the API [`info.version`](#infoVersion) string.
127 | info | [Info Object](#infoObject) | **REQUIRED**. Provides metadata about the API. The metadata MAY be used by tooling as required.
128 | servers | [[Server Object](#serverObject)] | An array of Server Objects, which provide connectivity information to a target server. If the `servers` property is not provided, or is an empty array, the default value would be a [Server Object](#serverObject) with a [url](#serverUrl) value of `/`.
129 | paths | [Paths Object](#pathsObject) | **REQUIRED**. The available paths and operations for the API.
130 | components | [Components Object](#componentsObject) | An element to hold various schemas for the specification.
131 | security | [[Security Requirement Object](#securityRequirementObject)] | A declaration of which security mechanisms can be used across the API. The list of values includes alternative security requirement objects that can be used. Only one of the security requirement objects need to be satisfied to authorize a request. Individual operations can override this definition.
132 | tags | [[Tag Object](#tagObject)] | A list of tags used by the specification with additional metadata. The order of the tags can be used to reflect on their order by the parsing tools. Not all tags that are used by the [Operation Object](#operationObject) must be declared. The tags that are not declared MAY be organized randomly or based on the tools' logic. Each tag name in the list MUST be unique.
133 | externalDocs | [External Documentation Object](#externalDocumentationObject) | Additional external documentation.
134 |
135 | This object MAY be extended with [Specification Extensions](#specificationExtensions).
136 | ```
137 |
138 | **Change: Add to the end of the table**
139 |
140 | ```
141 | webhooks | [[Webhooks Object](#webhooksObject)] | The incoming webhooks that may be received as part of this API.
142 | ```
143 |
144 | ### Describe a new Webhook Object
145 |
146 | (new spec section)
147 |
148 | ```
149 | #### Webhooks Object
150 |
151 | A map of webhooks that may be received as incoming HTTP requests as part of the API. The key of the map is a unique short name for the webhook e.g. `messageEvent`. Each value in the map is a [Path Item Object](#pathItemObject) that describes a set of requests that may be initiated by the API provider and the expected responses.
152 |
153 | Webhook Objects differ from [Callback Objects](#callbackObject) in that the webhooks are the result of some external event, not an earlier API call to subscribe or cause some other effect.
154 |
155 | ##### Webhook Object Example
156 |
157 | The following example shows an incoming webhook delivering a status update for a particular item ID:
158 |
159 | ````yaml
160 | webhooks:
161 | statusUpdate:
162 | requestBody:
163 | description: Status updates on an item. You can set the URL for these updates in your example.com dashboard.
164 | content:
165 | 'application/json':
166 | schema:
167 | type: object
168 | required:
169 | - item_id
170 | - status
171 | properties:
172 | item_id:
173 | type: string
174 | description: The ID of the item
175 | example: 0a000000012345678
176 | status:
177 | type: integer
178 | description: The status of this message, zero for success
179 | example: 14
180 | responses:
181 | '200':
182 | description: webhook successfully processed and no retries will be performed
183 |
184 | ```
185 |
186 | ## Backwards compatibility
187 |
188 | Adding a new top-level entry is not something to take lightly, however hopefully most tools will simply ignore what they weren't expecting and continue to operate on the parts of the spec they do understand until their functionality catches up with the spec change.
189 |
190 | ## Alternatives considered
191 |
192 | Another option is to add a special `path` that could contain the various webhooks using the existing `callback` syntax but existing tools which aren't expecting this special value may not handle it well, so this option was discounted.
193 |
--------------------------------------------------------------------------------
/proposals/2019-10-31-Clarify-Nullable.md:
--------------------------------------------------------------------------------
1 | # Clarify Semantics of `nullable` in OpenAPI 3.0
2 |
3 |
4 | ## Metadata
5 |
6 | |Tag |Value |
7 | |---- | ---------------- |
8 | |Proposal |[2019-10-31-Clarify-Nullable](https://github.com/OAI/OpenAPI-Specification/tree/main/proposals/2019-10-31-Clarify-Nullable.md)|
9 | |Authors|[Ted Epstein](https://github.com/tedepstein)|
10 | |Review Manager |TBD|
11 | |Status |Promoted|
12 | |Implementations |N/A|
13 | |Issues | [1900](https://github.com/OAI/OpenAPI-Specification/issues/1900), [1368](https://github.com/OAI/OpenAPI-Specification/issues/1368), [1389](https://github.com/OAI/OpenAPI-Specification/issues/1389), [1957](https://github.com/OAI/OpenAPI-Specification/pull/1957), [2046](https://github.com/OAI/OpenAPI-Specification/pull/2046), [1977](https://github.com/OAI/OpenAPI-Specification/pull/1977#issuecomment-533333957), [2057](https://github.com/OAI/OpenAPI-Specification/issues/2057)|
14 | |Previous Revisions |N/A |
15 |
16 | ## Change Log
17 |
18 | |Date |Responsible Party |Description |
19 | |---- | ---------------- |------------|
20 | |Oct 31, 2019 | Ted Epstein | Initial proposal |
21 | |Apr 8, 2021 | Ted Epstein | Update status to Promoted. The proposal was adopted in [OpenAPI 3.0.3](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md). |
22 |
23 | ## Introduction
24 |
25 | This proposal aims to clarify the semantics of the `nullable` keyword in OpenAPI 3.0. This clarification would resolve ambiguities, reinforce the intended alignment with JSON Schema, and provide guidance for schema validators, translators, and other tools.
26 |
27 | ## Motivation
28 |
29 | The documentation of the `nullable` keyword is incomplete and ambiguous, leaving many questions unanswered, and causing significant difficulty in reconciling certain assumed semantics with JSON Schema.
30 |
31 | To summarize the problems:
32 |
33 | * `nullable: true` is an _expanding assertion_ that doesn't fit JSON Schema's constraint-based processing model. It is not clear how it interacts with other keywords, and within what scope.
34 |
35 | * `nullable: false`, which is the default value, is not clearly defined, and could be interpreted in a way that breaks fundamental assumptions of JSON Schema.
36 |
37 | * Different OpenAPI schema validators and other tool implementations are likely to have different behaviors because the semantics of `nullable` are not fully specified.
38 |
39 | * Because of the above ambiguities, it is not clear how to translate an OpenAPI Schema Object into a standard JSON Schema for message validation and for other purposes. Some possible interpretations of the OpenAPI spec could make translating to JSON Schema much more difficult.
40 |
41 | * Depending on the interpretation, `nullable` might interact with `oneOf` and `anyOf` in problematic and counter-intuitive ways.
42 |
43 | The solution proposed herein should:
44 |
45 | * Clarify the boundaries around `nullable` so we know how it interacts with other assertions, applicators, subtypes and supertypes within its context.
46 |
47 | * Clarify the meaning of `nullable: false`.
48 |
49 | * Reaffirm the intended alignment of OpenAPI's Schema Object with JSON Schema, and reconcile `nullable` with JSON Schema semantics.
50 |
51 | * Allow a straightforward translation from `nullable` in OpenAPI to type arrays in JSON Schema.
52 |
53 | Further details follow.
54 |
55 | ### Primary Use Case for `nullable`
56 |
57 | A Schema Object allows values of any data type, unless the type is restricted by the `type` keyword. The `type` keyword restricts the schema to a single data type, which can be `"string"`, `"number"`, `"integer"`, `"boolean"`, `"array"`, or `"object"`, but cannot be `"null"`.
58 |
59 | Some APIs restrict values to a single data type, but also allow explicit null values. OpenAPI Schema Objects can allow explicit null values by combining the `type` and `nullable` keywords. A `nullable` value of `true` modifies a typed schema to allow non-null values of a given type, and also allow `null`. This was the envisioned use case, and the primary motivation for introducing `nullable` into the OpenAPI 3.0 spec.
60 |
61 | There may be other possible usage scenarios or consequences of the `nullable` keyword, the way it is specified, or the way in which the spec may be interpreted or implemented. In our view, these other scenarios should be considered side effects or oversights. To the best of our knowledge, the `nullable` keyword was not intended for any purpose other than to allow `null` in a typed schema.
62 |
63 | ### Expanding vs. Constraining Assertions
64 |
65 | `nullable: true` is an _expanding assertion_, meaning it has the effect of expanding the range of acceptable values. By contrast, JSON Schema's central operating principle is constraint-based, where _constraining assertions_ are cumulative, immutable, and each constraint has veto power to disallow some range of values.
66 |
67 | The semantics of constraining assertions are well-defined by JSON Schema and implemented in many JSON Schema validators and other tools. But JSON Schema doesn't have expanding assertions, so those well-defined semantics don't apply to `nullable`.
68 |
69 | To address this, we need to translate `nullable: true` into a constraining assertion. Otherwise, we would have to specify in detail how `nullable` interacts with constraining assertions like `enum` and with boolean applicators like `allOf` and `anyOf`.
70 |
71 | ### Interpretation of `nullable: false`
72 |
73 | The documentation specifies that `nullable: false` is the default, but doesn't clearly state what that means.
74 |
75 | One reasonable interpretation suggests that null values are disallowed unless `nullable` is explicitly set to `true`. This breaks a fundamental rule of JSON Schema, which states that an empty object `{}` is a valid schema that permits all values, with no constraints. Breaking that rule takes OpenAPI's Schema Object even further out of alignment with JSON Schema's processing model.
76 |
77 | For example, if null values are disallowed by default, does the following `UTCDate` schema accept `null`?
78 |
79 | ```yaml
80 | components:
81 |
82 | schemas:
83 |
84 | OptionalDate:
85 | type: string
86 | format: date
87 | nullable: true
88 |
89 | UTCDate:
90 | allOf:
91 | - $ref: "#/components/schemas/OptionalDate"
92 | not:
93 | type: string
94 | pattern: "^.*Z.*$"
95 | ```
96 |
97 | `UTCDate` does not specify a type of its own, and does not directly specify `nullable: true`. So if `null` is disallowed by default, even for untyped schemas, then `UTCDate` won't accept nulls. If we want it to accept nulls, we have to repeat `nullable: true` in `UTCDate`. This is not at all intuitive for API designers, and it breaks with JSON Schema's rule that any value is allowed unless it's explicitly disallowed.
98 |
99 | On the other hand, we could say that `UTCDate` inherits `nullable: true` from `OptionalDate`, therefore null values are allowed. But this kind of inheritance logic is completely foreign to JSON Schema. So this behavior is also counterintuitive, though for a different reason. It's also difficult to implement. Any JSON Schema validator would need to be hacked in highly disruptive ways to retrofit this behavior. Or a preprocessor would have to be introduced to propagate the effect of `nullable: true` through the `*Of` inheritance hierarchy.
100 |
101 | Whichever semantics we choose, it gets very messy.
102 |
103 | ### A closer look at `nullable: false`
104 |
105 | In fact, the OpenAPI 3.0 specification doesn't explicitly say that untyped schemas disallow null values.
106 |
107 | Here are the relevant parts:
108 |
109 | #### Data Types
110 | > Primitive data types in the OAS are based on the types supported by the JSON Schema Specification Wright Draft 00. Note that integer as a type is also supported and is defined as a JSON number without a fraction or exponent part. null is not supported as a type (see nullable for an alternative solution). Models are defined using the Schema Object, which is an extended subset of JSON Schema Specification Wright Draft 00.
111 |
112 | To say that null is "not supported _as a type_" would definitely disallow `type: "null"` in a schema object. But it doesn't necessarily mean that an untyped schema disallows _null values_.
113 |
114 | #### Definition of `nullable`
115 | > Allows sending a null value for the defined schema. Default value is false.
116 |
117 | This uses the word "allows," but there's no mention of "disallows." To say that `nullable: true` _allows_ null where it would otherwise be prohibited, doesn't necessarily mean that `nullable: false` _disallows_ null where it would otherwise be allowed.
118 |
119 | `nullable: true` _modifies_ a typed schema by adding null to the allowed types. `nullable: false` could mean "no null values allowed" or it could just mean "no modification to the specified type assertion, if any."
120 |
121 | #### Schema Object
122 | > The following properties are taken from the JSON Schema definition but their definitions were adjusted to the OpenAPI Specification.
123 | >
124 | > type - Value MUST be a string. Multiple types via an array are not supported.
125 |
126 | There is no specified adjustment to the `type` property that disallows null values. So it should defer to the JSON Schema specification, which says that, in the absence of a `type` assertion, any valid JSON value is allowed.
127 |
128 | So the 3.0 spec is ambiguous about null values. It's not clear whether the spec intended to disallow null values by default, even in untyped schemas. This looks more like an accidental oversight, or an unfortunate choice of words, than a clear intention.
129 |
130 | ### Specific Questions
131 |
132 | Questions that are not answered by the current specification include the following:
133 |
134 | * If a schema specifies `nullable: true` and `enum: [1, 2, 3]`, does that schema allow null values? (See [#1900](https://github.com/OAI/OpenAPI-Specification/issues/1900).)
135 |
136 | * Does an untyped schema (without a `type` keyword) allow null values by default? What effect, if any, does `nullable: true` have on an untyped schema?
137 |
138 | * Can `allOf` be used to define a nullable subtype of a non-nullable base schema? (See [#1368](https://github.com/OAI/OpenAPI-Specification/issues/1368).)
139 |
140 | * Can `allOf` be used to define a non-nullable subtype of a nullable base schema?
141 |
142 | * What is the correct translation of a nullable schema from OpenAPI into an equivalent JSON Schema?
143 |
144 | * Is `null` allowed as the `default` value of a nullable schema? (See [#2057](https://github.com/OAI/OpenAPI-Specification/issues/2057).)
145 |
146 | ## Proposed solution
147 |
148 | We propose to clarify the 3.0 specification in the next patch release, to resolve these questions and align OpenAPI's Schema Object with JSON Schema's well-defined, constraint-based semantics.
149 |
150 | In our view, and consistent with the original intent, `nullable` should have a very limited, well-defined scope. It should satisfy the primary use case, i.e. allowing `null` in a typed schema, with minimal side effects.
151 |
152 | This is the proposed replacement for the `nullable` definition:
153 |
154 |
155 | Field Name | Type | Description
156 | ---|:---:|---
157 | nullable | `boolean` | A `true` value adds `"null"` to the allowed type specified by the `type` keyword, only if `type` is explicitly defined within the same Schema Object. Other Schema Object constraints retain their defined behavior, and therefore may disallow the use of `null` as a value. A `false` value leaves the specified or default `type` unmodified. The default value is `false`.
158 |
159 |
160 | ## Detailed design
161 |
162 | According to the above specification, `nullable` only operates within a narrow scope, wherein its translation to JSON Schema is straightforward:
163 |
164 | * `nullable` is only meaningful if its value is `true`.
165 |
166 | * `nullable: true` is only meaningful in combination with a `type` assertion specified in the same Schema Object. `nullable` acts as a `type` modifier, allowing `null` in addition to the specified type.
167 |
168 | * `nullable: true` operates within a single Schema Object. It does not "override" or otherwise compete with supertype or subtype schemas defined with `allOf` or other applicators. It cannot be directly "inherited" through those applicators, and it cannot be applied to an inherited `type` constraint.
169 |
170 | This also solves the issues of alignment with JSON Schema:
171 |
172 | * Since `type` is a constraint, JSON Schema's constraint-based processing model is fully applicable. Interactions between `type` and other constraining assertions and applicators are unambiguous, with each constraint having independent veto power.
173 |
174 | * It is now clear that `nullable: false`, whether explicit or by default, _does not_ prohibit null values. Consistent with JSON Schema, an empty object allows all values, including `null`.
175 |
176 | ### Questions Answered
177 |
178 | Following are answers to the questions posed above, assuming the proposed clarification is adopted:
179 |
180 | #### If a schema specifies `nullable: true` and `enum: [1, 2, 3]`, does that schema allow null values? (See [#1900](https://github.com/OAI/OpenAPI-Specification/issues/1900).)
181 |
182 | No. The `nullable: true` assertion folds into the `type` assertion, which presumably specifies `integer` or `number`.
183 |
184 | While the modified `type` now allows `null`, the `enum` does not. Consistent with JSON schema, a value conforms to the schema only if it is valid against _all_ constraints. Any constraint, in this case `enum`, can cause a value to fail validation, even if that value meets all of the other constraints.
185 |
186 | #### Does an untyped schema (without a `type` keyword) allow null values by default? What effect, if any, does `nullable: true` have on an untyped schema?
187 |
188 | Yes, an untyped schema allows null values, in addition to all other types. `nullable: true` has no effect, because null values are already allowed. And `nullable: false` has no effect because it just leaves the `type` constraint unmodified.
189 |
190 | #### Can `allOf` be used to define a nullable subtype of a non-nullable base schema? (See [#1368](https://github.com/OAI/OpenAPI-Specification/issues/1368).)
191 |
192 | No. Subtypes can add constraints, but not relax them.
193 |
194 | #### Can `allOf` be used to define a non-nullable subtype of a nullable base schema?
195 |
196 | Yes. The subtype can specify a `type` without `nullable: true`, or can specify `not: {enum: [null]}`.
197 |
198 | #### What is the correct translation of a nullable schema from OpenAPI into an equivalent JSON Schema?
199 |
200 | A nullable type should translate into a type array with two string elements: the name of the type specified in the Schema Object, and `"null"`.
201 |
202 | #### Is `null` allowed as the `default` value of a nullable schema? (See [#2057](https://github.com/OAI/OpenAPI-Specification/issues/2057).)
203 |
204 | Yes. For example, a Schema Object with `"type" : "string", "nullable" : true` would translate to a JSON Schema with `"type" : ["string", "null"]`. That schema permits `"default" : null`, even with the [strict typing rule](https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.0.md#properties) specified by OpenAPI 3.0:
205 |
206 | > default - The default value represents what would be assumed by the consumer of the input as the value of the schema if one is not provided. Unlike JSON Schema, the value MUST conform to the defined type for the Schema Object defined at the same level. For example, if `type` is `string`, then `default` can be `"foo"` but cannot be `1`.
207 |
208 | ## Backwards compatibility
209 |
210 | Spec revisions through 3.0.2 are ambiguous as described above, so any possible clarification has the potential to break existing implementations.
211 |
212 | With the clarification of `nullable: false`, we think the risk of actual breakage is miniscule, because the current ambiguity only affects untyped Schema Objects, which by their nature leave a lot of room for unexpected values. Any implementation that relies on schema validation to prevent null values should use explicitly typed schemas, and typed schemas unambiguously disallow `null` unless `nullable` is `true`.
213 |
214 | There might be a somewhat greater risk of breakage by specifying the effect of `nullable: true` as a `type` modifier. A more heavy-handed interpretation of `nullable: true`, [described here](https://github.com/OAI/OpenAPI-Specification/issues/1900#issuecomment-486772917), would make it equivalent to `anyOf [s, {type: "null"}]` where `s` is the schema as specified (excluding `nullable`). This would allow nulls even where they would be prohibited by other schema keywords, like `enum`. But this interpretation introduces far greater complexity than the narrowly scoped `type` modifier. We are not aware of any OpenAPI schema validator that actually attempts this, and there is nothing in the OpenAPI spec that says `nullable` can override constraining assertions.
215 |
216 | ## Alternatives considered
217 |
218 | [Pull request #1977](https://github.com/OAI/OpenAPI-Specification/pull/1977#issuecomment-533333957) has some history of other approaches considered along the way. The first attempt assumed that `nullable: false` would prohibit null values, and attempted to work around this while maintaining backward compatibility.
219 |
220 | On closer inspection, the specification does not say anything about `null` values being disallowed. So we believe our interpretation is correct, and highly advantageous in its alignment with JSON Schema.
221 |
--------------------------------------------------------------------------------
/proposals/2019-12-24-Overlays.md:
--------------------------------------------------------------------------------
1 | # Overlays
2 |
3 | ## Metadata
4 |
5 | |Tag |Value |
6 | |---- | ---------------- |
7 | |Proposal |[2019-12-24-Overlays](https://github.com/OAI/OpenAPI-Specification/tree/main/proposals/2019-12-24-Overlays.md)|
8 | |Authors|[Darrel Miller](https://github.com/darrelmiller)|
9 | |Status |Proposal|
10 | |Issues |[1442](https://github.com/OAI/OpenAPI-Specification/issues/1442) [1722](https://github.com/OAI/OpenAPI-Specification/issues/1722)|
11 |
12 | ## Change Log
13 |
14 | |Date |Responsible Party |Description |
15 | |---- | ---------------- | ---------- |
16 | | 24th December 2019 | Darrel Miller | Initial draft |
17 | | 2nd January 2019 | Darrel Miller | Update to wording around removing items from arrays. Added section on backward compatibility. Clarified process around applying a set of updates. Started to add supported scenarios.|
18 | | 29th July 2020 | Darrel Miller | Updated to be explicit about update operations |
19 |
20 | ## Introduction
21 |
22 | In recent months we have been discussing various use cases for overlays and various solutions. The following proposal takes a somewhat more radical approach to the problem. It is a more ambitious proposal than the others we have seen before but the additional complexity does allow for supporting many of the scenarios that have been discussed to date.
23 |
24 | #### Overlay Document
25 |
26 | An overlay document contains a list of [Update Objects](#overlayUpdates) that are to be applied to the target document. Each [Update Object](#updateObject) has a `target` property and a `value` property. The `target` property is a [JMESPath](http://jmespath.org/specification.html) query that identifies what part of the target document is to be updated and the `value` property contains an object with the properties to be overlaid.
27 |
28 |
29 | #### Overlay Object
30 |
31 | This is the root object of the [OpenAPI Overlay document](#oasDocument).
32 |
33 | ##### Fixed Fields
34 |
35 | Field Name | Type | Description
36 | ---|:---:|---
37 | overlay | `string` | Version of the Overlay specification that this document conforms to.
38 | info | [[Info Object](#overlayInfoObject)] | Identifying information about the overlay.
39 | extends | `url` | URL to an OpenAPI document this overlay applies to.
40 | updates | [[Update Object](#updateObject)] | A list of update objects to be applied to the target document.
41 |
42 | The list of update objects MUST be applied in sequential order to ensure a consistent outcome. Updates are applied to the result of the previous updates. This enables objects to be deleted in one update and then re-created in a subsequent update.
43 |
44 | The `extends` property can be used to indicate that the Overlay was designed to update a specific OpenAPI description. This is an optional property. Where no `extends` is provided it is the responsibility of tooling to apply the Overlay documents to the appropriate OpenAPI description.
45 |
46 | #### Info Object
47 |
48 | This object contains identifying information about the [OpenAPI Overlay document](#oasDocument).
49 |
50 | ##### Fixed Fields
51 |
52 | Field Name | Type | Description
53 | ---|:---:|---
54 | title | `string` | A human readable description of the purpose of the overlay.
55 | version | `string` | A version identifier for indicating changes to an overlay document.
56 |
57 | #### Update Object
58 |
59 | This object represents one or more changes to be applied to the target document at the location defined by the target JMESPath.
60 |
61 | ##### Fixed Fields
62 |
63 | Field Name | Type | Description
64 | ---|:---:|---
65 | target | `string` | A JMESPath expression referencing the target objects in the target document.
66 | add | [Any](#addObject) | An object to be added as a child of the object(s) referenced by the target. Property has no impact if `remove` property is `true`.
67 | merge | [Any](#mergeObject) | An object with the properties and values to be merged with the object(s) referenced by the target. Property has no impact if `remove` property is `true`.
68 | remove | `boolean` | A boolean value that indicates that the target object is to be removed from the the map or array it is contained in. The default value is false.
69 |
70 | The properties of the merge object MUST be compatible with the target object referenced by the JMESPath key. When the Overlay document is applied, the properties in the merge object replace properties in the target object with the same name and new properties are appended to the target object.
71 |
72 | ##### Structured Overlays Example
73 |
74 | When updating properties throughout the target document it may be more efficient to create a single `Update Object` that mirrors the structure of the target document. e.g.
75 |
76 | ```yaml
77 | overlay: 1.0.0
78 | info:
79 | title: Structured Overlay
80 | version: 1.0.0
81 | updates:
82 | - target: "@"
83 | merge:
84 | info:
85 | x-overlay-applied: structured-overlay
86 | paths:
87 | "/":
88 | summary: "The root resource"
89 | get:
90 | summary: "Retrieve the root resource"
91 | x-rate-limit: 100
92 | "/pets":
93 | get:
94 | summary: "Retrieve a list of pets"
95 | x-rate-limit: 100
96 | components:
97 | tags:
98 | ```
99 |
100 | ##### Targeted Overlays
101 |
102 | Alternatively, where only a small number of updates need to be applied to a large document, each [Update Object](#updateObject) can be more targeted.
103 |
104 | ```yaml
105 | overlay: 1.0.0
106 | info:
107 | title: Targeted Overlays
108 | version: 1.0.0
109 | updates:
110 | - target: paths."/foo".get
111 | merge:
112 | description: This is the new description
113 | - target: paths."/bar".get
114 | merge:
115 | description: This is the updated description
116 | - target: paths."/bar"
117 | merge:
118 | post:
119 | description: This is an updated description of a child object
120 | x-safe: false
121 | ```
122 |
123 | ##### Wildcard Overlays Examples
124 |
125 | One significant advantage of using the JMESPath syntax that it allows referencing multiple nodes in the target document. This would allow a single update object to be applied to multiple target objects using wildcards.
126 |
127 | ```yaml
128 | overlay: 1.0.0
129 | info:
130 | title: Update many objects at once
131 | version: 1.0.0
132 | updates:
133 | - target: paths.*.get
134 | merge:
135 | x-safe: true
136 | - target: paths.*.get.parameters[?name=='filter' && in=='query']
137 | merge:
138 | schema:
139 | $ref: "/components/schemas/filterSchema"
140 | ```
141 |
142 | ##### Array Modification Examples
143 |
144 | Due to the fact that we can now reference specific elements of the parameter array, it allows adding parameters. Parameters can be deleted using the `remove` property. Use of indexes to remove array items should be avoided where possible as indexes will change when items are removed.
145 |
146 | ```yaml
147 | overlay: 1.0.0
148 | info:
149 | title: Add an array element
150 | version: 1.0.0
151 | updates:
152 | - target: paths.*.get.parameters
153 | add:
154 | name: newParam
155 | in: query
156 | ```
157 |
158 | ```yaml
159 | overlay: 1.0.0
160 | info:
161 | title: Remove a array element
162 | version: 1.0.0
163 | updates:
164 | - target: paths[*].get.parameters[? name == 'dummy']
165 | remove: true
166 | ```
167 |
168 | ##### Traits Examples
169 |
170 | By annotating an OpenAPI description using extension such as `x-oai-traits` an author of OpenAPI description can identify where overlay updates should be applied.
171 |
172 | ```yaml
173 | openapi: 3.1.0
174 | info:
175 | title: Api with a paged collection
176 | version: 1.0.0
177 | paths:
178 | /items:
179 | get:
180 | x-oai-traits: ["paged"]
181 | responses:
182 | 200:
183 | description: OK
184 | ```
185 |
186 | With the above OpenAPI description, following Overlay document will apply the necessary updates to describe how paging is implemented, where that trait has been applied.
187 |
188 | ```yaml
189 | overlay: 1.0.0
190 | info:
191 | title: Apply Traits
192 | version: 1.0.0
193 | updates:
194 | - target: $.paths[*].get[?contains(x-traits,'paged')]
195 | merge:
196 | parameters:
197 | - name: top
198 | in: query
199 | - name: skip
200 | in: query
201 | ```
202 |
203 | This approach allows flipping control of where Overlays apply updates to the OpenAPI description itself.
204 |
205 | ## Proposal Summary
206 |
207 | ### Benefits
208 |
209 | - This approach addresses the two distinct approaches of structured overlay vs targeted overlay which suits distinct but equally valid scenarios.
210 | - Addresses the problem of modifying the parameters array and removes the need to replace the entire array when a small change is required.
211 | - Allows sets of related overlays to be stored in a same file.
212 | - Enables updating a set of objects based on a pattern. This might be an effective way of apply common behaviour across many operations in an API.
213 |
214 | ### Challenges
215 |
216 | - Tooling will need a JMESPath implementation.
217 | - Large overlays may be slow to process.
218 | - Multiple complex pattern based overlays may cause overlapping updates causing confusing outcomes.
219 |
220 | ## Alternatives considered
221 |
222 | JMESPath was chosen over JSONPath due to the fact that JMESPath has a [specification](http://jmespath.org/specification.html) and a set of test cases. This will help to ensure compatibility between implementations.
223 |
224 | ## Backwards compatibility
225 |
226 | Overlays will be described in a new specification that can be used alongside an OpenAPI Description, therefore there will be no compatibility issues for the initial release. Overlay documents can be used against OpenAPI v2 and v3 descriptions.
227 |
228 | ## Scenarios Considered
229 |
230 | - Multi-language support. An Overlay document for each language is used to target a specific OpenAPI description. The Overlay document will likely use a duplicate structure to the original OpenAPI description and replace all `description` properties.
231 | - Applying API wide standards. An Overlay document contains update objects that describe standard headers, parameters, responses. These documents would use JMESPath queries to target the appropriate objects in the OpenAPI description. Tooling could be used to target the OpenAPI description rather than using extends.
232 | - Add tool specific OpenAPI metadata. Overlay adds additional metadata such as SLA information, client codegen hints or middleware policies. Using Overlays to manage this data separately is valuable when there is a different audience for the data and/or there the information has different sensitivity levels.
233 |
--------------------------------------------------------------------------------
/proposals/2020-10-28-Experimental.md:
--------------------------------------------------------------------------------
1 | # Experimental marker
2 |
3 | ## Metadata
4 |
5 | |Tag |Value |
6 | |---- | ---------------- |
7 | |Proposal |[Experimental](https://github.com/OAI/OpenAPI-Specification/blob/main/proposals/2020-10-28-Experimental.md)|
8 | |Authors|[David Goss](https://github.com/davidjgoss)|
9 | |Review Manager |TBD |
10 | |Status |Proposal|
11 | |Implementations ||
12 | |Issues ||
13 | |Previous Revisions ||
14 |
15 | ## Change Log
16 |
17 | |Date |Responsible Party |Description |
18 | |---- | ---------------- | ---------- |
19 |
20 | ## Introduction
21 |
22 | A way to mark an aspect of the API as "experimental", indicating that it is not yet a fully stable and supported part of the API.
23 |
24 | ## Motivation
25 |
26 | Consider an API with two categories of thing in it:
27 |
28 | - Core, stable things, where we are committed to the ongoing stability and have no intention of making breaking changes.
29 | - New, experimental things, where we are getting them out there for feedback and early adopters, but they may change before we consider them to be in the first category, or even just get removed.
30 |
31 | These sit together fine in principle, but cause friction when trying to apply something like semver to the API as a whole. How do we make changes to the experimental stuff - without bumping the major version several times a year and scaring consumers - while also ensuring we can't make breaking changes to the core stuff we never _want_ to break.
32 |
33 | ## Proposed solution
34 |
35 | Add an "experimental" field which specifies that an items in the API is not yet fully stable and supported, may change or be removed without a major version bump, and as such should be used with caution.
36 |
37 | _(I don't have a strong opinion about the naming - "beta" is another idea, though I think "experimental" does the job better in terms of being the most noncommital.)_
38 |
39 | Downstream tools could then make use of this metadata:
40 |
41 | - Tools like swagger-ui could surface this in the documentation they generate so consumers are made aware. Experimental items could also be filtered out of the documentation and stubs if desired.
42 | - Tools for detecting and preventing breaking changes could take this into consideration when deciding whether a change is breaking.
43 |
44 | ## Detailed design
45 |
46 | A new boolean field named `experimental`, defaulting to `false`, is added to:
47 |
48 | - Operation
49 | - Parameter
50 | - Schema
51 |
52 | This specifies that the operation, parameter or schema is not yet stable and SHOULD be used with caution.
53 |
54 | ### Operation Object
55 |
56 | ...
57 |
58 | ##### Fixed Fields
59 |
60 | Field Name | Type | Description
61 | ---|:---:|---
62 | ... | ... | ...
63 | experimental | `boolean` | Specifies that an operation is in experimental status, meaning it may change outside of the normal breaking change process. Consumers SHOULD use with caution. Default value is `false`.
64 |
65 | ### Parameter Object
66 |
67 | ...
68 |
69 | ##### Fixed Fields
70 |
71 | Field Name | Type | Description
72 | ---|:---:|---
73 | ... | ... | ...
74 | experimental | `boolean` | Specifies that a parameter is in experimental status, meaning it may change outside of the normal breaking change process. Consumers SHOULD use with caution. Default value is `false`. Cannot be `true` when the parameter is `required`.
75 |
76 | ### Schema Object
77 |
78 | ...
79 |
80 | ##### Fixed Fields
81 |
82 | Field Name | Type | Description
83 | ---|:---:|---
84 | ... | ... | ...
85 | experimental | `boolean` | Specifies that a schema is in experimental status, meaning it may change outside of the normal breaking change process. Consumers SHOULD use with caution. Default value is `false`.
86 |
87 | ### Example Spec
88 |
89 | ```yaml
90 | /asset/constraints:
91 | get:
92 | tags:
93 | - Asset
94 | - Constraints
95 | summary: Get a set of asset constraints
96 | operationId: constraints
97 | parameters:
98 | - name: siteToken
99 | in: query
100 | description: Site token obtained from Site API
101 | required: true
102 | schema:
103 | type: string
104 | experimental: true
105 | ```
106 | ### Prior Art
107 |
108 | This kind of requirement is handled for TypeScript libraries by [api-extractor](https://api-extractor.com/pages/tsdoc/doc_comment_syntax/#release-tags) - they have both "alpha" and "beta" markers with a somewhat opinionated flow attached - I'm not sure that level of granularity is necessary. But the "beta" and "public" ones map well to the motivations described here:
109 |
110 | > - **beta**: Indicates that an API item has been released as a preview or for experimental purposes. Third parties are encouraged to try it and provide feedback. However, a “beta” API should NOT be used in production, because it may be changed or removed in a future version.
111 | > - **public**: Indicates that an API item has been officially released, and is now part of the supported contract for a package. If the SemVer versioning scheme is used, then the API signature cannot be changed without a MAJOR version increment.
112 |
113 | ### Unanswered Questions
114 |
115 | - If an operation is not marked as experimental, but it is using a schema which is (i.e. as its request object), then it is implicitly also unstable. Would this usage be considered invalid?
116 |
117 | ## Backwards compatibility
118 |
119 | The `experimental` field would default to false, meaning existing behaviour is preserved, and the new field is only used on an opt-in basis.
120 |
121 | `experimental` can coexist with `deprecated` - an operation, parameter or schema can be both experimental and deprecated, having never gotten to a stable point before being deprecated.
122 |
123 | ## Alternatives considered
124 |
125 | - _Specification extensions_ - publishers could add an extension in their own domain, but the benefit of the metadata being available to downstream tools (including those used by consumers, not just publishers) would be lost.
126 | - _Tags_ - as above, but this also gets to mixing other kinds of metadata in with resource taxonomy, which seems wrong.
127 | - _Overlays_ - The [Overlays proposal](https://github.com/OAI/OpenAPI-Specification/blob/main/proposals/2019-12-24-Overlays.md) is sufficiently powerful to be able to implement this, with a canonical spec representing the stable API and an overlay used to apply experimental additions. Downsides: not as ergonomic for authors, the OpenAPI specification would still not have "experimental" as a first-class concept so there'd be reliance on conventions being observed across the ecosystem for how it's done with overlays.
128 | - _Different API_ - this would be the least messy from a technical perspective - maintain a completely separate API for experimental items, and then "promote" them to the main API once they are considered stable. This has increased overhead for publishers and consumers, and could also reduce the likelihood of getting feedback on, and early uptake of, experimental items if they are segregated in a different place altogether.
129 |
130 |
--------------------------------------------------------------------------------
/proposals/2024-08-01-Self-Identification.md:
--------------------------------------------------------------------------------
1 | # Self-Identification
2 |
3 | ## Metadata
4 |
5 | |Tag |Value |
6 | |---- | ---------------- |
7 | |Proposal |[2024-08-01 Self-Identification](https://github.com/OAI/OpenAPI-Specification/tree/main/proposals/{2024-08-01-Self-Identification-and-Bundling.md})|
8 | |Relevant Specification(s)|OpenAPI Specification (OAS), Arazzo Specification|
9 | |Authors|[Henry Andrews](https://github.com/handrews)|
10 | |Review Manager | TBD |
11 | |Status |Proposal|
12 | |Implementations |n/a|
13 | |Issues | |
14 | |Previous Revisions | |
15 |
16 | ## Change Log
17 |
18 | |Date |Responsible Party |Description |
19 | |---- | ---------------- | ---------- |
20 | |2024-08-01 | @handrews | Initial submission
21 |
22 | ## Introduction
23 |
24 | OpenAPI 3.1 references are treated as identifiers rather than locators. This behavior is inherited from JSON Schema 2020-12, and is made more explicit in the forthcoming OAS 3.1.1 patch release. This separation can support stable, self-assigned identifiers which allow certain sorts of OpenAPI Description refactoring _without_ having to re-write the values of `"$ref"` and similar keywords. However, OAS lacks a mechanism to fully define such identifiers within each document, which substantially limits the benefits of this separation.
25 |
26 | ## Motivation
27 |
28 | One of the main motivations for separating identity (URIs/IRIs) and location (URLs) is to have stable, persistent identifiers regardless of the resource's location. Such identifiers are typically assigned within the resource. There are two varieties:
29 |
30 | * Setting the complete resource's absolute URI, which is also used as the resource's base URI per [RFC3986 §5.1.1](https://www.rfc-editor.org/rfc/rfc3986.html#section-5.1.1) (example: [the Schema Object's `$id`](https://www.ietf.org/archive/id/draft-bhutton-json-schema-01.html#name-the-id-keyword))
31 | * Setting a ["plain name" URI fragment](https://www.w3.org/TR/2012/WD-fragid-best-practices-20121025/#dfn-plain-name-fragid) that does not rely on the JSON/YAML structure of the document (example: [the Schema Object's `$anchor`](https://www.ietf.org/archive/id/draft-bhutton-json-schema-01.html#name-defining-location-independe), and technically also `$dynamicAnchor` although this proposal will not mention `$dynamicAnchor` further as its additional complexities are not relevant here).
32 |
33 | As suggested by the above examples, in OAS 3.1 only the Schema Object can set stable, location-independent identifiers. OpenAPI Description documents as a whole cannot do so, nor can other Objects within the document.
34 |
35 | Note also that due to the recursive structure of schemas, resolving the Schema Object's `$id` keyword can be complex, as each can itself be a relative URI-reference that is resolved against the `$id` in parent schemas. There is no clear use case for such complexity within other parts of an OpenAPI Description.
36 |
37 | ### Use Cases
38 |
39 | There are several use cases for separating identity and location, including:
40 |
41 | * Working around network challenges:
42 | * Restrictive network security policies
43 | * Intermittent connectivity
44 | * High latency / low bandwidth
45 | * Document hosts that [require authentication](https://github.com/OAI/OpenAPI-Specification/issues/3270)
46 | * Abstracting development vs testing vs deployment details
47 | * Allowing `.json` and `.yaml` file extensions during development, as is preferred by most IDEs
48 | * Using extensions in development and HTTP content negotiation in production
49 | * Differing source control repository structure (particularly of shared documents) vs deployment directory and server layouts
50 | * This separation is necessary (although not, on its own, sufficient) to implement [bundling](https://www.openapis.org/blog/2021/08/23/json-schema-bundling-finally-formalised).
51 |
52 | For a more detailed real-world example, see the [OGC example](https://github.com/OAI/sig-moonwalk/discussions/72#user-content-ogc) in the Moonwalk discussion on imports.
53 |
54 | Many of these use cases can be worked around, but only by restricting deployment options or performing error-prone reference target rewriting. Many tools that perform reference rewriting do not take into account the added complexities of referencing in OAS 3.1 compared to 3.0 and earlier.
55 |
56 | ### Prior Art
57 |
58 | Self-identification of resources with identity independent of location is common in the JSON Schema world. This demonstrates that implementation is not just feasible but well-proven, particularly given that JSON Schema's `$id` is more complex to support than this proposal.
59 |
60 | The JSON Schema package used by the [OASComply](https://github.com/OAI/oascomply) project includes a [schema catalog](https://jschon.readthedocs.io/en/latest/tutorial/catalog.html) with [configurable file and network sources](https://jschon.readthedocs.io/en/latest/examples/file_based_schemas.html) to manage the URI-to-URL mapping (local files can be considered `file:` URLs).
61 |
62 | Self-identification is common in other formats as well. Notably, the Atom format pioneered the use of [web links with `rel="self"`](https://www.rfc-editor.org/rfc/rfc4287.html#section-4.2.7.2) for this purpose.
63 |
64 | ## Proposed solution
65 |
66 | The proposal is a simplified analog of JSON Schema's `$id` that appears in exactly one place: a new `self` field in the root OpenAPI Object (OAS) and Arazzo Object (Arazzo). When referencing a document that has a `self` field, the `self` field SHOULD be used in reference values so that reference values remain the same even if the document is moved.
67 |
68 | Placing the `self` field only in the OpenAPI Object or Arazzo Object makes it align with the existing bootstrapping process for parsing:
69 |
70 | 1. Check the `openapi` or `arazzo` field in the root OpenAPI or Arazzo Object to determine the specification version
71 | 1. Check the `jsonSchemaDialect` field for the default Schema Object dialect
72 | 1. Determine the base URI per RFC3986 §5.1.2-5.1.4 (in most cases, use the retrieval URL per §5.1.3)
73 | 1. ***NEW*** Check the `self` field for a base URI per RFC3986 §5.1.1; if it exists, resolve it against the base URI from the previous step and use the result as the document's actual base URI
74 | 1. Continue parsing the remainder of the document as usual
75 |
76 | As [OAS 3.1.1 clarifies](https://github.com/OAI/OpenAPI-Specification/pull/3758), it is already mandatory to separate location and identity for Schema Object support.
77 |
78 | Currently, associating a URI other than the current URL with a document to meet this requirement has to be done externally. Many tools effectively support this by allowing the retrieval URL to be set manually, without verifying that the document actually lives at the given URL. However, this relies on users to make use of a non-standard implementation feature rather than offering well-defined behavior based on the document author's intent.
79 |
80 | With the new `self` field, tools need to be configured to know how to locate documents whose `self` values do not match their locations. The JSON Schema implementation linked under [Prior Art](#prior-art) above demonstrates several ways to accomplish this.
81 |
82 | ## Detailed design
83 |
84 | This is written for the structure of the OAS, but it should be clear how it would be adapted for Arazzo. Some amount of guidance around how to configure tools to resolve `self`-references that do not match locations probably also needs to be added in the sections on reference resolution and base URIs.
85 |
86 | ```MARKDOWN
87 | ## OpenAPI Object
88 |
89 | ### Fixed Fields
90 |
91 | Field Name | Type | Description
92 | ---|:---|:---
93 | self | `URI-reference` (without a fragment) | Sets the URI of this document, which also serves as its base URI in accordance with [RFC 3986 §5.1.1](https://www.rfc-editor.org/rfc/rfc3986#section-5.1.1); the value MUST NOT be the empty string and MUST NOT contain a fragment
94 | ```
95 |
96 | ## Backwards compatibility
97 |
98 | OAS 3.2 and Arazzo 1.1 documents that do not use the `self` field will behave exactly the same as OAS 3.1 and Arazzo 1.0 documents. The change in minor version is sufficient to manage the compatibility issues, as no software that only supports up to 3.1/1.0 should attempt to parse 3.2/1.1 documents.
99 |
100 | ## Alternatives considered
101 |
102 | ### Plain name fragments in every Object
103 |
104 | While including `self` in every Object would produce the same complexity as JSON Schema's nested `$id`, we could just adopt an equivalent of JSON Schema's `$anchor` keyword, which (like HTML/XML's `id` attribute) creates a plain name fragment that is not tied to the location of the Object in the JSON/YAML structure.
105 |
106 | Handling a fragment declaration keyword would require scanning all Objects for the keyword prior to declaring that a reference target with a plain name fragment cannot be resolved. This would likely be done on document load, but could be deferred and done incrementally as-needed when unknown fragments are encountered.
107 |
108 | Support for `$anchor` in JSON Schema demonstrates that this is feasible, and the mental model is familiar to most from HTML. But it would be a bit more work to support.
109 |
110 | While it would be a significant advantage to have completely location-independent referencing support, this is given as an alternative because the `self` field is a pre-requisite, and can be added whether we later support plain name fragments or not.
111 |
--------------------------------------------------------------------------------
/proposals/2024-09-01-Tags-Improvement.md:
--------------------------------------------------------------------------------
1 | # Tags Improvement
2 |
3 |
4 | ## Metadata
5 |
6 | |Tag |Value |
7 | |---- | ---------------- |
8 | |Proposal |[2024-09-01-Tags-Improvement](https://github.com/OAI/OpenAPI-Specification/tree/main/proposals/{2024-09-01-Tags-Improvement.md})|
9 | |Authors|[Lorna Mitchell](https://github.com/lornajane)|
10 | |Review Manager | TBD |
11 | |Status |Proposal|
12 | |Implementations | |
13 | |Issues | [1367](https://github.com/OAI/OpenAPI-Specification/issues/1367), [2843](https://github.com/OAI/OpenAPI-Specification/issues/2843), |
14 | |Previous Revisions | None, but see [Moonwalk discussion](https://github.com/OAI/sig-moonwalk/discussions/67)
15 |
16 | ## Change Log
17 |
18 | |Date |Responsible Party |Description |
19 | |---- | ---------------- | ---------- |
20 | | 2024-09-01 | @lornajane | Initial draft |
21 |
22 | ## Introduction
23 |
24 | Evolve the existing `tags` implementation to (optionally) support more use cases, such as giving the tags some grouping/relationships and adding more metadata.
25 |
26 | ## Motivation
27 |
28 | The tags feature hasn't changed since the spec was still called Swagger, but it's one of the most-extended aspects of OpenAPI with most tools supporting some sort of grouping or additional metadata. One motivation for this proposal is to "pave the cowpath" and formalise some of the patterns from those extensions as part of the specification.
29 |
30 | The existing tags implementation is also quite limiting, so users/tools feel they "cannot" use tags, because they are so widely implemented for documentation navigation and required exactly one tag per operation, to be used only for this single purpose or to be opted out using extensions such as `x-traitTag`. The result is that we see lots of extensions that add arbitrary metadata to operations, some of them even become part of the specification officially (looking at you, `deprecated: true`) or being so widely used that we should probably adopt them (`x-internal`, `x-experimental`). The specification does have a way of tagging operations, but it's too limited and the result is that everything has to be added as an extension field.
31 |
32 | On a personal note, I work for a tool vendor and was proposing these changes internally; but the problems affect all OpenAPI users so I brought it to the main project.
33 |
34 | ### Supporting evidence
35 |
36 | There are several examples "in the wild" of where a better tags implementation would have helped. Here is a selection of publicly-accessible examples to illustrate some of the problems this proposal could help with:
37 |
38 | - Grouping of tags is a very common use case, almost everyone uses some sort of extra hierarchy to group the tags themselves, which makes sense as our APIs are only getting more complex, something like [`x-tagGroups`](https://redocly.com/docs/api-reference-docs/specification-extensions/x-tag-groups/) is a good example - and there's a [very active open issue on OpenAPI specification itself](https://github.com/OAI/OpenAPI-Specification/issues/1367)
39 | - Various tag-alike additions exist, sometimes called "badges" or similar; I'd include extensions such as [`x-internal`](https://redocly.com/docs/cli/guides/hide-apis/#step-1-add-x-internal-to-the-api-description) as a tag-alike since they could be tags if more than one tag (or tag type) could be applied.
40 | - Additional display metadata is also in active use in the wild, see [`x-displayName`](https://redocly.com/docs/api-reference-docs/specification-extensions/x-display-name) and this [OpenAPI specification issue](https://github.com/OAI/OpenAPI-Specification/issues/2843)
41 |
42 | ## Proposed solution
43 |
44 | Originally proposed in a [Moonwalk discussion](https://github.com/OAI/sig-moonwalk/discussions/67), I am proposing three backwards-compatible additions to the existing tags feature:
45 |
46 | * Tags get a `summary` alongside `name` and `description`. In keeping with our existing practices: name is the identifier, summary is the short display content, and description is available in contexts where more information is appropriate.
47 | * A `parent` field is added to support a hierarchy without adding either separators or a new data type. Your tag can belong to another tag.
48 | * A `kind` field to explain which family of tags this tag belongs to (previously proposed as `type`). We'd expecting these to be `nav`, `badge`, `internal` and probably some other things that other tooling types would find useful.
49 |
50 | An example could look something like this:
51 |
52 | ```yaml
53 | tags:
54 | - name: deprecated
55 | kind: internal
56 | summary: Deprecated
57 | description: This operation has been deprecated and will be removed in the future. Avoid using items with this tag.
58 | - name: shop
59 | kind: nav
60 | summary: Order Online
61 | description: Operations relating to the retail operations behind the [online shopping site](https://example.com/shopping).
62 | - name: products
63 | kind: nav
64 | parent: shop
65 | summary: Products
66 | description: View and manage the product catalog.
67 | - name: orders
68 | kind: nav
69 | parent: shop
70 | summary: Online Orders
71 | description: Place, fulfil and invoice orders for the online shop.
72 |
73 | ```
74 |
75 | Rather than making an allowed list of kinds, we will instead leave that open for user extension and keep a list of the recommended/expected types in a registry and evolve that as conventions emerge.
76 |
77 | ## Detailed design
78 |
79 | The following section is an updated specification section, for the top-level tags object only (no other changes are needed):
80 |
81 | ---
82 |
83 | #### Tag Object
84 |
85 | Adds metadata to a single tag that is used by the [Operation Object](#operation-object).
86 | Each tag used in the Operation Object instances MAY have a Tag Object defined.
87 |
88 | ##### Fixed Fields
89 |
90 | Field Name | Type | Description
91 | ---|:---:|---
92 | name | `string` | **REQUIRED**. The name of the tag. Use this value in the `tags` array of an Operation.
93 | summary | `string` | A short summary of the tag, used for display purposes.
94 | description | `string` | A description for the tag. [CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text representation.
95 | externalDocs | [External Documentation Object](#external-documentation-object) | Additional external documentation for this tag.
96 | parent | `string` | The `name` of a tag that this tags is nested under. The named tag MUST exist in the API description, and circular references between parent and child tags MUST NOT be used.
97 | kind | `string` | A machine-readable string to categorize what sort of tag it is. Common uses are `nav` for Navigation, `badge` for badges, `internal` for internal APIs, but any string value can be used. A registry of known values is available.
98 |
99 | This object MAY be extended with [Specification Extensions](#specification-extensions).
100 |
101 | ##### Tag Object Example
102 |
103 | ```json
104 | {
105 | "name": "account-updates",
106 | "summary": "Account Updates",
107 | "description": "Account update operations",
108 | "kind": "nav"
109 | },
110 | {
111 | "name": "partner",
112 | "summary": "Partner",
113 | "description": "Operations available to the partners network",
114 | "parent": "external",
115 | "kind": "audience"
116 | },
117 | {
118 | "name": "external",
119 | "summary": "External",
120 | "description": "Operations available to external consumers",
121 | "kind": "audience"
122 | }
123 | ```
124 |
125 | ```yaml
126 | - name: account-updates
127 | summary: Account Updates
128 | description: Account update operations
129 | kind: nav
130 |
131 | - name: partner
132 | summary: Partner
133 | description: Operations available to the partners network
134 | parent: external
135 | kind: audience
136 |
137 | - name: external
138 | summary: External
139 | description: Operations available to external consumers
140 | kind: audience
141 | ```
142 |
143 | ---
144 |
145 | ## Backwards compatibility
146 |
147 | All new fields are optional, so existing API descriptions will remain valid and useful.
148 | Some users may wish to adopt some of the following steps on upgrade:
149 |
150 | - Set `kind: nav` if their existing tags are currently used for navigation entries in documentation tooling.
151 | - Change `x-displayName` in `tag` objects to `summary` instead.
152 | - Add a tag to replace each `x-tagGroups` entry, and set the `parent` field for each of the tags in the groups.
153 | - Change `x-badges` extensions to instead be a tag with `kind: badge`.
154 | - Change features like `x-internal` to be a tag with a specific `kind` set. Similarly some lifecycle use cases such as `x-beta` could be replaced with tags.
155 |
156 | ## Alternatives considered
157 |
158 | - Continue to use tags as-is, and extend the spec for each use case that users need rather than providing an open metadata implementation.
159 | We've been slow to iterate and I would rather "open" the options than try to control them.
160 | The API space evolves quite quickly.
161 |
162 | - Set `children` rather than `parent` on the tags and operate a top-down relationship.
163 | The suggestion of allowing multiple links or a graph approach was also mentioned.
164 | In both cases, there are good ideas in every direction, but our responsibility is to implement a structure that users can easily understand and maintain.
165 |
166 |
--------------------------------------------------------------------------------
/proposals/2025-03-20-URIs-for-Tags.md:
--------------------------------------------------------------------------------
1 | # URIs for Tags
2 |
3 |
4 | ## Metadata
5 |
6 | |Tag |Value |
7 | |---- | ---------------- |
8 | |Proposal |[2025-03-20-URIs-for-Tags](https://github.com/OAI/OpenAPI-Specification/tree/main/proposals/{2025-03-20-URIs-for-Tags.md})|
9 | |Authors|[Henry Andrews](https://github.com/handrews)|
10 | |Review Manager | [Lorna Mitchell](https://github.com/lornajane) |
11 | |Status | rejected |
12 | |Implementations | n/a |
13 | |Issues |[#2905 Allow the use of $ref and json pointer in tags](https://github.com/OAI/OpenAPI-Specification/issues/2905), consolidated into [#3853 Consolidated $ref-to-Some Object feature request](https://github.com/OAI/OpenAPI-Specification/issues/3853)|
14 | |Previous Revisions |n/a|
15 |
16 | ## Change Log
17 |
18 | |Date |Responsible Party |Description |
19 | |---- | ---------------- | ---------- |
20 | |2025-03-20 | @handrews | Initial publication |
21 | |2025-03-26 | @handrews | Document rejection |
22 |
23 | ## Introduction
24 |
25 | Tags are the last remaining [implicit connection](https://spec.openapis.org/oas/v3.1.1#resolving-implicit-connections) that do not have a URI-based alternative for deterministic, universal referencing (Security Requirement Objects are fixed in [PR #4388](https://github.com/OAI/OpenAPI-Specification/pull/4388), currently awaiting re-approval after review feedback changes).
26 | This proposal adds such an alternative, giving tags the same capabilities as all other similar mechanisms within the OAS.
27 |
28 | ## Motivation
29 |
30 | ### A user request and proposal
31 |
32 | From @SandroG in issue #2905 (which is only closed because it was consolidated into #3853), which got two further thumbs-ups:
33 |
34 | _**[NOTE:** The mechanism proposed here is **not** the one favored by this proposal, which is explained further down]_
35 |
36 | > I have a large specification, which I need to break down in different files. I use an approach where each file is like a sub-specification that lists all endpoints regarding the same subject and then I include these endpoints in the main openapi file.
37 | > The documentation of a tag is in the same file as the endpoint that uses it.
38 | >
39 | > I'm not able to reuse that tag declaration in the main file, so I'm not able to include the description of the tag.
40 | >
41 | > For example, I have a separate file for customer's endpoints
42 |
43 | `customers.yaml`
44 | ```YAML
45 | info:
46 | ...
47 | tags:
48 | - name: Customer
49 | description: APIs to manage customers. A customer is a representation of ...
50 |
51 | paths:
52 | /customers/{id}/:
53 | parameters:
54 | - name: id
55 | . . .
56 | get:
57 | . . .
58 | /customers/:
59 | . . .
60 | ```
61 | > I need to do this:
62 |
63 | `openapi.yaml`
64 | ```YAML
65 | info:
66 | ...
67 | tags:
68 | - $ref: "./customers.yaml#/tags/0"
69 |
70 | paths:
71 | /customers/{id}/:
72 | $ref: "./customers.yaml#/paths/~customers~1{id}~1"
73 | /customers/:
74 | $ref: "./customers.yaml#/paths/~customers~1"
75 | ```
76 |
77 | ### Proof of confusion over tag to Tag Object resolution
78 |
79 | In the above example, @SandroG proposes using `$ref` for Tag Objects to pull Tag Objects from one [OpenAPI Document](https://spec.openapis.org/oas/v3.1.1#openapi-document) into another, where they can be used by the `tags` field in Operation Objects.
80 | This makes clear that they expect tags to be resolved from the _current document_, which may be a [referenced document rather than the entry document](https://spec.openapis.org/oas/v3.1.1#openapi-description).
81 |
82 | However, in [3.0.4](https://spec.openapis.org/oas/v3.0.4#resolving-implicit-connections) and [3.1.1](https://spec.openapis.org/oas/v3.1.1#resolving-implicit-connections) we RECOMMEND (== SHOULD) that tag names are resolved to Tag Objects in the _entry document_.
83 | This means that there is no way to resolve them from the current document, which is the mirror image of the problem as that encountered by @SandroG.
84 |
85 | In today's TDC call, @lornajane stated that she expects tag names to be resolved from the entry document, and @kevinswiber expressed doubt that anyone implements anything else (sadly @SandroG does not mention their tool, which presumably resolves from the current document or else they would not have explained the issue in this way).
86 |
87 | ### Fragility of JSON Pointers with arrays
88 |
89 | Tag Objects are ordered, and tools MAY treat the ordering as significant for presentation purposes. JSON Pointers include the array index, which will change whenever someone decides to re-order the tag display, breaking any URI references that include a JSON Pointer.
90 | However, the use of the `name` field and the requirement that all Tag Objects in a list have a unique name mean that it is only necessary to identify the OpenAPI Object (or as a simpler proxy, the OpenAPI Document) in which to find the list of Tag Objects.
91 | Once the correct OpenAPI Document is identified, the list can be searched by name as it is now.
92 |
93 | ### Additional scenarios
94 |
95 | Another scenario to consider is a standards group that is publishing OpenAPI Documents that are intended to be used by multiple API providers.
96 | Such standards groups have no control over the entry documents used, so if they wish to provide Tag Objects, they MUST place them in the shared, referenced document.
97 | If the API provider wishes to use those Tag Objects in their entry document, or in their own referenced documents, then they currently cannot do.
98 |
99 | ## Proposed solution
100 |
101 | A new field or fields would be added to identify, with a URI, the OpenAPI Document from which a tag MUST be resolved.
102 | This would bring tags into alignment with other implicitly resolved names (e.g. Schema names in the Discriminator Object and Security Scheme names in the Security Requirement Object), with the variation that only the Document rather than the exact Object is identified.
103 |
104 | ## Detailed design
105 |
106 | In the Tag Object, a `parentDocument` field would be an optional URI qualifier to the `parent` field, and only allowed if `parent` is present.
107 |
108 | In the Operation Object, a `tagRefs` field would be added alongside the `tags` field.
109 | This new field would be a map with a Document URI as the keys, and an array of tags (as in the `tags` field) as the values.
110 | Tags under `tagRefs` would be resolved within the document identified by the key, while tags within `tags` would continue to be RECOMMENDED to resolve from the entry document.
111 |
112 | ## Backwards compatibility
113 |
114 | The proposal is fully backwards compatible.
115 |
116 | ## Alternatives considered
117 |
118 | The option proposed by @SandroG would require the Operation Object's `tags` field to resolve from the current document, which would be a breaking change and therefore not possible in 3.2.
119 |
120 | @baywet proposed a top-level (per-document) association of URIs and tags, to reduce the number of places where it is necessary to look for URIs.
121 | However, this requires duplicating tags that would otherwise only appear in Operation Objects in the top-level field, and does not fully solve the namespacing issue as each tag could only resolve from one place, rather than allowing the same tag name to have different meanings by resolving it to a different Tag Object in a different document.
122 |
123 | @karenetheridge proposed treating tags like `operationId` and resolving within the entire description (a PR to this proposal with more details of this alternative would be welcome).
124 | To me, `operationId` is not a good precedent to follow, as we already have to provide numerous disclaimers regarding collisions in the specification text, and the results are not well-defined.
125 | While we could make collisions an error for this new mechanism, @baywet noted that trying to prevent such collisions is highly burdensome in large organizations (although @karenetheridge similarly pointed to experience of it working).
126 | The fact that `operationRef` had to be included to provide a URI-based alternative to using `operationId` in the Link Object is a strong piece of evidence in favor of a URI-based solution for tags.
127 |
128 | ## Outcome
129 |
130 | Rejected per @lornajane, with concurrence by @ralfhandl:
131 |
132 | > I am not in favour of these additions for the 3.x branch. I wish that we'd implemented tags differently in the first place, and I'm sure that all the constructive discussion around the tags feature will help us a lot in future major releases.
133 | >
134 | > I believe that the limitations of the current tag situation can be overcome with helper tooling and that this change (while solving a narrow but valid use case) adds complexity to the specification that is unnecessary and does not benefit the majority of users. As custodians of a widely-used standard, we have a responsibility to maintain something that is appropriate for its audience, and we should be "reluctant" in all our changes unless we see that they are really needed.
135 | >
136 | > I propose that users would be equally well served by leaving the requirement to resolve tags from the entry document. Organisations can either maintain an extensive list of tags in all OpenAPI documents, and then remove any that aren't used before publishing (tooling exists for this use case), or alternatively if a tool wants to include tags found in the wider context of referenced OpenAPI documents by adding them to the top-level tags array during processing, that would work well too.
137 | >
138 | > The tags array is a list of strings. It isn't an ID like the Operation uses, and it's not a named entry like the security schemes, so it is appropriate to approach the limitations of it differently. My proposal is to offer some advice or documentation on approaching this problem, but not to bring it in scope of the specification for 3.x since other options are available.
139 |
--------------------------------------------------------------------------------
/proposals/Alternative-Schema/CONTRIBUTORS.md:
--------------------------------------------------------------------------------
1 | * Chuck Heazel [@cmheazel](https://github.com/cmheazel)
2 | * Darrel Miller [@darrelmiller](https://github.com/darrelmiller)
--------------------------------------------------------------------------------
/proposals/Alternative-Schema/alternative_schema_object.md:
--------------------------------------------------------------------------------
1 | ## Change: Add the Alternative Schema Object
2 |
3 | The following text is to be inserted after the XML Object section
4 |
5 | ### Alternative Schema Object
6 |
7 | This object makes it possible to reference an external file that contains a schema that does not follow the OAS specification. If tooling does not support the _type_, tooling MUST consider the content valid but SHOULD provide a warning that the alternative schema was not processed.
8 |
9 | ## Fixed Fields
10 |
11 | |Field Name | Type | Description |
12 | |---|:---:|---|
13 | |type | string | **REQUIRED**. The value MUST match one of the values identified in the alternative Schema Registry. |
14 | |location | url | **REQUIRED**. This is a absolute or relative reference to an external resource containing a schema of a known type. This reference may contain a fragment identifier to reference only a subset of an external document. |
15 |
16 | This object MAY be extended with Specification Extensions.
17 |
18 |
--------------------------------------------------------------------------------
/proposals/Alternative-Schema/examples.md:
--------------------------------------------------------------------------------
1 | ## Change: Add Alternative Schema Examples
2 |
3 | The following text is to be inserted after the Alternative Schema Object section.
4 |
5 | ### Alternative Schema Examples
6 |
7 | Minimalist usage of alternative schema:
8 |
9 | schema:
10 | x-oas-draft-alternativeSchema:
11 | type: jsonSchema
12 | location: ./real-jsonschema.json
13 |
14 | Combination of OAS schema and alternative:
15 |
16 | schema:
17 | type: object
18 | nullable: true
19 | x-oas-draft-alternativeSchema:
20 | type: jsonSchema
21 | location: ./real-jsonschema.json
22 |
23 | Multiple different versions of alternative schema:
24 |
25 | schema:
26 | anyOf:
27 | - x-oas-draft-alternativeSchema:
28 | type: jsonSchema
29 | location: ./real-jsonschema-08.json
30 | - x-oas-draft-alternativeSchema:
31 | type: jsonSchema
32 | location: ./real-jsonschema-07.json
33 |
34 | Combined alternative schemas:
35 |
36 | schema:
37 | allOf:
38 | - x-oas-draft-alternativeSchema:
39 | type: xmlSchema
40 | location: ./xmlSchema.xsd
41 | - x-oas-draft-alternativeSchema:
42 | type: schematron
43 | location: ./schema.sch
44 |
45 | Mixed OAS schema and alternative schema:
46 |
47 | schema:
48 | type: array
49 | items:
50 | x-oas-draft-alternativeSchema:
51 | type: jsonSchema
52 | location: ./real-jsonschema.json
53 |
54 |
--------------------------------------------------------------------------------
/proposals/Alternative-Schema/implementations.md:
--------------------------------------------------------------------------------
1 | # Implementations
2 |
3 | ## Overview
4 |
5 | Below is a list of tooling that claims to implement the Alternative Schema proposal. While support for this feature matures, refer to the details of projects listed below for any notes about stability and roadmap. The process to improve the OpenAPI specification includes feedback from end-users and tooling creators. We strongly encourage draft tooling be made available for early users of OAS drafts.
6 |
7 | These tools are not endorsed by the OAI
8 |
9 | ## Implementations:
10 |
11 | #### Low-Level tooling
12 |
13 | | Title | Project Link | Language | Description
14 | | ----------- | ----------- | ----------- | -----------
15 | |TBD |TBD |TBD |TBD |
16 |
17 | #### Editors
18 |
19 | | Title | Project Link | Language |Description |
20 | |----------------|--------------|----------|---------------------|
21 | |TBD |TBD |TBD |TBD |
22 |
23 | #### User Interfaces
24 |
25 | | Title | Project Link | Language |Description |
26 | |----------------|--------------|----------|---------------------|
27 | |TBD |TBD |TBD |TBD |
28 |
29 | #### Mock Servers
30 | | Title | Project Link | Language | Description |
31 | | -------------- | ------------ | -------- | ----------- |
32 | |TBD |TBD |TBD |TBD |
33 |
34 | #### Server Implementations
35 | | Title | Project Link | Language |Description |
36 | |----------------|--------------|----------|---------------------|
37 | |TBD |TBD |TBD |TBD |
38 |
39 | #### Code Generators
40 |
41 | | Title | Project Link | Language |Description |
42 | |----------------|--------------|----------|---------------------|
43 | |TBD |TBD |TBD |TBD |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/proposals/Alternative-Schema/schema_object.md:
--------------------------------------------------------------------------------
1 | ## Change: Extend the Schema Object to support Alternative Schemas
2 |
3 | The following content shall be used to replace the Fixed Fields table in the Schema Object section
4 |
5 | #### Fixed Fields
6 |
7 | |Field Name | Type | Description |
8 | |---|:---:|---|
9 | | nullable | `boolean` | Allows sending a `null` value for the defined schema. Default value is `false`.|
10 | | discriminator | [Discriminator Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.2.md#discriminatorObject) | Adds support for polymorphism. The discriminator is an object name that is used to differentiate between other schemas which may satisfy the payload description. See [Composition and Inheritance](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.2.md#schemaComposition) for more details. |
11 | | readOnly | `boolean` | Relevant only for Schema `"properties"` definitions. Declares the property as "read only". This means that it MAY be sent as part of a response but SHOULD NOT be sent as part of the request. If the property is marked as `readOnly` being `true` and is in the `required` list, the `required` will take effect on the response only. A property MUST NOT be marked as both `readOnly` and `writeOnly` being `true`. Default value is `false`. |
12 | | writeOnly | `boolean` | Relevant only for Schema `"properties"` definitions. Declares the property as "write only". Therefore, it MAY be sent as part of a request but SHOULD NOT be sent as part of the response. If the property is marked as `writeOnly` being `true` and is in the `required` list, the `required` will take effect on the request only. A property MUST NOT be marked as both `readOnly` and `writeOnly` being `true`. Default value is `false`. |
13 | | xml | [XML Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.2.md#xmlObject) | This MAY be used only on properties schemas. It has no effect on root schemas. Adds additional metadata to describe the XML representation of this property. |
14 | | externalDocs | [External Documentation Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.2.md#externalDocumentationObject) | Additional external documentation for this schema.
15 | | example | Any | A free-form property to include an example of an instance for this schema. To represent examples that cannot be naturally represented in JSON or YAML, a string value can be used to contain the example with escaping where necessary.|
16 | | deprecated | `boolean` | Specifies that a schema is deprecated and SHOULD be transitioned out of usage. Default value is `false`.|
17 | |x-oas-draft-alternativeSchema |alternative Schema Object |An external schema that participates in the validation of content along with other schema keywords. |
18 |
--------------------------------------------------------------------------------
/style-guide.md:
--------------------------------------------------------------------------------
1 | # Style Guide
2 |
3 | Contributions to this repository should follow the style guide as described in this section.
4 |
5 | ## Markdown
6 |
7 | Markdown files in this project should follow the style enforced by the [markdownlint tool](https://www.npmjs.com/package/markdownlint),
8 | as configured by the `.markdownlint.yaml` file in the root of the project.
9 | The `markdownlint` tool can also fix formatting, which can save time with tables in particular.
10 |
11 | The following additional rules should be followed but currently are not enforced by tooling:
12 |
13 | 1. The first mention of a normative reference or an OAS-defined Object in a (sub)*section is a link, additional mentions are not.
14 | 2. OAS-defined Objects such as Schema Objects are written in this style, and are not monospaced.
15 | 3. Use "example" instead of "sample" - this spec is not about statistics.
16 | 4. Use "OpenAPI Object" instead of "root".
17 | 5. Fixed fields are monospaced.
18 | 6. Field values are monospaced in JSON notation: `true`, `false`, `null`, `"header"` (with double-quotes around string values).
19 | 7. A combination of fixed field name with example value uses JS notation: `in: "header"`, combining rules 5 and 6.
20 | 8. An exception to 5-7 is colloquial use, for example "values of type `array` or `object`" - "type" is not monospaced, so the monospaced values aren't enclosed in double quotes.
21 | 9. Use [Oxford commas](https://en.wikipedia.org/wiki/Serial_comma), avoid [Shatner commas](https://www.latimes.com/archives/blogs/jacket-copy/story/2011-06-30/goodbye-oxford-comma-hello-shatner-comma).
22 | 10. Use `` for link anchors. The `` format has been deprecated.
23 | 11. Headings use [title case](https://en.wikipedia.org/wiki/Title_case) and are followed by a blank line.
24 | 12. Do not use [RFC2119 key words (MUST, MAY, ...)](https://datatracker.ietf.org/doc/html/rfc2119) in "Examples" sections or when explaining examples, and state requirements only in sections that are clearly normative.
25 | 13. Bullet lists and punctuation:
26 | - If a bullet list item is a complete sentence or paragraph, start it with an uppercase letter and end it with a period.
27 | - If a bullet list item is a word or short phrase, start it with an uppercase letter and do not end it with a punctuation character.
28 | - If a bullet list item completes a stem sentence immediately preceding the bullet list, start it with a lowercase letter and end it with a period.
29 | - Use a consistent bullet list item style for each bullet list.
30 | - If in doubt which style to use for a new bullet list, look for similar lists in the same section or nearby sections and choose the same style.
31 |
32 | Plus some suggestions, rather than rules:
33 |
34 | * Use one sentence per line in paragraphs and bullet points, to make diffs and edits easier to compare and understand.
35 | A blank line is needed to cause a paragraph break in Markdown.
36 | * In examples, use realistic values rather than foo/bar.
37 |
38 | ## Use of "keyword", "field", "property", and "attribute"
39 |
40 | * JSON Schema keywords -> "keyword"
41 | * OpenAPI fixed fields -> "field"
42 | * property of a "plain" JSON object that is not an OpenAPI-defined Foo Object -> "property"
43 | * "attribute" is only used in the XML context and means "XML attribute"
44 |
45 | ## Field Names and Values in YAML comments
46 |
47 | Field names and keywords should be in backticks.
48 | Values like "Dog" should be double quoted.
49 |
--------------------------------------------------------------------------------
/tests/md2html/README.md:
--------------------------------------------------------------------------------
1 | To view the HTML files in folder `fixtures` with respec formatting, you can
2 | ~~~sh
3 | mkdir js
4 | cp ../../node_modules/respec/builds/respec-w3c.js js/
5 | echo "*" > js/.gitignore
6 | ~~~
7 | and open them in a local browser.
8 |
--------------------------------------------------------------------------------
/tests/md2html/fixtures/basic-new.md:
--------------------------------------------------------------------------------
1 | # Heading 1
2 |
3 | Text for first chapter
4 |
5 | ## Version 30.0.1
6 |
7 | This is the conformance section
8 |
9 | ## Heading 2
10 |
11 | Text for first section
12 |
13 | ## Definitions
14 |
15 | ### Foo
16 |
17 | Definition of Foo.
18 |
19 | ## Another Heading 2
20 |
21 | Text for second section
22 |
23 | [Relative link to example](../examples/foo.yaml)
24 |
25 | [Relative link to something else](../something/else)
26 |
27 | ### Heading 3
28 |
29 | Text for first subsection
30 |
31 | [RFC3986](https://datatracker.ietf.org/doc/html/rfc3986)
32 |
33 | [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#section-4)
34 |
35 | ```json
36 | {
37 | "foo": true
38 | }
39 | ```
40 |
41 | ```yaml
42 | foo: true
43 | ```
44 |
45 | ```text
46 | text/plain
47 | ```
48 |
49 | ```
50 | no language
51 | ```
52 |
53 | ```unknown
54 | unknown language
55 | ```
56 |
57 | ```uri
58 | https://foo.com/bar?baz=qux&fred=waldo#fragment
59 | ```
60 |
61 | ```uritemplate
62 | https://foo.com/bar{?baz*,qux}
63 | ```
64 |
65 | ```multipart
66 | --boundary-example
67 | Content-Type: application/openapi+yaml
68 | Content-Location: https://inaccessible-domain.com/api/openapi.yaml
69 |
70 | openapi: 3.2.0
71 | info:
72 | title: Example API
73 | version: 1.0
74 | externalDocs:
75 | url: docs.html
76 |
77 | --boundary-example
78 | Content-Type: text/html
79 | Content-Location: https://example.com/api/docs.html
80 |
81 |
82 |
83 | API Documentation
84 |
85 |
86 | Awesome documentation goes here
87 |
88 |
89 | ```
90 |
91 | ```eventstream
92 | event: addString
93 | data: This data is formatted
94 | data: across two lines
95 | retry: 5
96 |
97 | event: addNumber
98 | data: 1234.5678
99 | unknownField: this is ignored
100 |
101 | : This is a comment
102 | event: addJSON
103 | data: {"foo": 42}
104 | ```
105 |
106 | ```jsonl
107 | {"event": "addString", "data": "This data is formatted\nacross two lines", "retry": 5}
108 | {"event": "addNumber", "data": "1234.5678"}
109 | {"event": "addJSON", "data": "{\"foo\": 42}"}
110 | ```
111 |
112 | ```ndjson
113 | {"event": "addString", "data": "This data is formatted\nacross two lines", "retry": 5}
114 | {"event": "addNumber", "data": "1234.5678"}
115 | {"event": "addJSON", "data": "{\"foo\": 42}"}
116 | ```
117 |
118 | ```jsonseq
119 | 0x1E{
120 | "timestamp": "1985-04-12T23:20:50.52Z",
121 | "level": 1,
122 | "message": "Hi!"
123 | }
124 | 0x1E{
125 | "timestamp": "1985-04-12T23:20:51.37Z",
126 | "level": 1,
127 | "message": "Bye!"
128 | }
129 | ```
130 |
131 | ## Appendix A: Revision History
132 |
133 | Version | Date
134 | --------|-----------
135 | 30.0.1 | 3001-04-01
136 |
--------------------------------------------------------------------------------
/tests/md2html/fixtures/basic-old.md:
--------------------------------------------------------------------------------
1 | # Heading 1
2 |
3 | Text for first chapter
4 |
5 | #### Version 30.0.1
6 |
7 | This is the conformance section
8 |
9 | ## Table of Contents
10 |
11 | Will be removed
12 |
13 | ## Heading 2
14 |
15 | Text for first section
16 |
17 | Broken anchor
18 |
19 | ### Heading 3
20 |
21 | Text for first subsection
22 |
23 |
24 | Version | Date
25 | --------|-----------
26 | 30.0.1 | 3001-04-01
27 |
--------------------------------------------------------------------------------
/versions/1.2.md:
--------------------------------------------------------------------------------
1 | # Swagger RESTful API Documentation Specification
2 |
3 | #### Version 1.2
4 |
5 | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC 2119](http://www.ietf.org/rfc/rfc2119.txt).
6 |
7 | The Swagger specification is licensed under [The Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.html).
8 |
9 | ## 1. Introduction
10 |
11 | Swagger™ is a project used to describe and document RESTful APIs.
12 |
13 | The Swagger specification defines a set of files required to describe such an API. These files can then be used by the Swagger-UI project to display the API and Swagger-Codegen to generate clients in various languages. Additional utilities can also take advantage of the resulting files, such as testing tools.
14 |
15 | ## 2. Revision History
16 |
17 | Version | Date | Notes
18 | --- | --- | ---
19 | 1.2 | 2014-03-14 | Initial release of the formal document.
20 | 1.1 | 2012-08-22 | Release of Swagger 1.1
21 | 1.0 | 2011-08-10 | First release of the Swagger Specification
22 |
23 | ## 3. Definitions
24 |
25 | - Resource: A `resource` in Swagger is an entity that has a set of exposed operations. The entity can represent an actual object (pets, users..) or a set of logical operations collated together. It is up to the specification user to decide whether sub-resources should be referred to as part of their main resource or as a resource of their own.
26 | For example, assume the following URL set:
27 | ```
28 | - /users - GET
29 | POST
30 | - /users/{id} - GET
31 | PATCH
32 | DELETE
33 | ```
34 | In this case, there's either one "/users" resource that contains operations on the "/users/{id}" sub-resource, or two separate resources.
35 |
36 | - URL: A fully qualified URL.
37 |
38 | ## 4. Specification
39 |
40 | ### 4.1 Format
41 |
42 | The files describing the RESTful API in accordance with the Swagger specification are represented as JSON objects and conform to the JSON standards.
43 |
44 | For example, if a field is said to have an array value, the JSON array representation will be used:
45 |
46 | ```js
47 | {
48 | "field" : [...]
49 | }
50 | ```
51 |
52 | Please note that while the API is described using JSON, the input and/or output can be in XML, YAML, plain text, or whichever format you chose to use with your API.
53 |
54 | Unless noted otherwise, all field names in the specification are **case sensitive**.
55 |
56 | ### 4.2 File Structure
57 |
58 | The Swagger representation of the API is comprised of two file types:
59 |
60 | 1. [**The Resource Listing**](#51-resource-listing) - This is the root document that contains general API information and lists the resources. Each resource has its own URL that defines the API operations on it.
61 |
62 | 1. [**The API Declaration**](#52-api-declaration) - This document describes a resource, including its API calls and models. There is one file per resource.
63 |
64 |
65 | ### 4.3 Data Types
66 |
67 | In the Swagger specification, the data types are used in several locations - [Operations](#523-operation-object), [Operation Parameters](#524-parameter-object), [Models](#527-model-object), and within the data types themselves (arrays).
68 |
69 | The fields used to describe a given data type are added flatly to the relevant object. For example, if an object Foo has the field `name`, and is also a data type, then it MUST also include the field `type` (or its variance, as explained ahead). In this example, Foo would look like:
70 | ```js
71 | "Foo" : {
72 | "name" : "sample",
73 | "type" : "string",
74 | ...
75 | }
76 | ```
77 |
78 | This section describes the general fields that are available to describe such data types. Some data types allow additional fields to extend further limitations on the data type *value* (see [4.3.3 Data Type Fields](#433-data-type-fields) for further details).
79 |
80 | Special care should be taken when referencing a model (or a complex type). There are currently two variations, and the proper variation should be documented everywhere the model may be used. This behavior will be unified in future versions of the spec.
81 |
82 | The Swagger specification supports five data types:
83 |
84 | 1. [`primitive`](#431-primitives) (input/output)
85 | 1. containers (as arrays/sets) (input/output)
86 | 1. [complex](#527-model-object) (as `models`) (input/output)
87 | 1. [`void`](#432-void) (output)
88 | 1. [`File`](#434-file) (input)
89 |
90 | #### 4.3.1 Primitives
91 |
92 | Different programming languages represent primitives differently. The Swagger specification supports by name only the primitive types supported by the [JSON-Schema Draft 4](http://json-schema.org/latest/json-schema-core.html#anchor8). However, in order to allow fine tuning a primitive definition, an additional [`format`](#dataTypeFormat) field MAY accompany the [`type`](#dataTypeType) primitive to give more information about the type used. If the [`format`](#dataTypeFormat) field is used, the respective client MUST conform to the elaborate type.
93 |
94 | Common Name | [`type`](#dataTypeType) | [`format`](#dataTypeFormat) | Comments
95 | ----------- | ------ | -------- | --------
96 | integer | `integer` | `int32` | signed 32 bits
97 | long | `integer` | `int64` | signed 64 bits
98 | float | `number` | `float` |
99 | double | `number` | `double` |
100 | string | `string` | |
101 | byte | `string` | `byte` |
102 | boolean | `boolean` | |
103 | date | `string` | `date` |
104 | dateTime | `string` | `date-time` |
105 |
106 | #### 4.3.2 `void`
107 |
108 | This value type is used to indicate that an [operation](#523-operation-object) returns no value. As such it MAY be used only for the return type of operations.
109 |
110 | #### 4.3.3 Data Type Fields
111 |
112 | As explained above, when an object is said to include a data type, there are a set of fields it may include (some are required and some are optional).
113 |
114 | Special care should be taken when referencing a model (or a complex type). There currently two variations, and the proper variation should be documented everywhere it may be used. This behavior will be unified in future versions of the spec.
115 |
116 | The table below shows the available fields to describe a data type. The `Validity` column may impose additional restrictions as to which data type is required in order to include this field. For example, [`enum`](#dataTypeEnum) may only be included if the [`type`](#dataTypeType) field is set to `string`.
117 |
118 | Field Name | Type | Validity |Description
119 | ---|:---:|---|---
120 | type | `string` | Any |**Required (if [`$ref`](#dataTypeRef) is not used).** The return type of the operation. The value MUST be one of the [Primitives](#431-primitives), `array` or a model's [`id`](#modelId).
121 | $ref | `string` | Any | **Required (if [`type`](#dataTypeType) is not used).** The [Model](#527-model-object) to be used. The value MUST be a model's [`id`](#modelId).
122 | format | `string` | primitive | Fine-tuned primitive type definition. See [Primitives](#431-primitives) for further information. The value MUST be one that is defined under [Primitives](#431-primitives), corresponding to the right primitive [`type`](#dataTypeType).
123 | defaultValue | *special* | primitive | The default value to be used for the field. The value type MUST conform with the primitive's [`type`](#dataTypeType) value.
124 | enum | [`string`] | `string` | A fixed list of possible values. If this field is used in conjunction with the [`defaultValue`](#dataTypeDefaultValue) field, then the default value MUST be one of the values defined in the `enum`.
125 | minimum | `string` | `number`, `integer` | The minimum valid value for the type, inclusive. If this field is used in conjunction with the [`defaultValue`](#dataTypeDefaultValue) field, then the default value MUST be higher than or equal to this value. The value type is `string` and should represent the minimum numeric value. **Note**: This will change to a numeric value in the future.
126 | maximum | `string` | `number`, `integer` | The maximum valid value for the type, inclusive. If this field is used in conjunction with the [`defaultValue`](#dataTypeDefaultValue) field, then the default value MUST be lower than or equal to this value. The value type is `string` and should represent the maximum numeric value. **Note**: This will change to a numeric value in the future.
127 | items | [Items Object](#434-items-object) | `array` | **Required.** The type definition of the values in the container. A container MUST NOT be nested in another container.
128 | uniqueItems | `boolean` | `array` | A flag to note whether the container allows duplicate values or not. If the value is set to `true`, then the `array` acts as a set.
129 |
130 | #### 4.3.4 Items Object
131 |
132 | This object is used to describe the value types used inside an array. Of the [Data Type Fields](#433-data-type-fields), it can include either the [`type`](#dataTypeType) and [`format`](#dataTypeFormat) fields *OR* the [`$ref`](#dataTypeRef) field (when referencing a model). The rest of the listed Data Type fields are not applicable.
133 |
134 | If the [`type`](#dataTypeType) field is included it MUST NOT have the value `array`. There's currently no support for containers within containers.
135 |
136 | ##### 4.3.4.1 Object Examples
137 |
138 | For a primitive type:
139 | ```js
140 | {
141 | "type": "string"
142 | }
143 | ```
144 |
145 | For a complex type (model):
146 |
147 | ```js
148 | {
149 | "$ref": "Pet"
150 | }
151 | ```
152 |
153 | #### 4.3.5 `File`
154 |
155 | The `File` (case sensitive) is a special type used to denote file upload. Note that declaring a model with the name `File` may lead to various conflicts with third party tools and SHOULD be avoided.
156 |
157 | When using `File`, the [`consumes`](#operationConsumes) field MUST be `"multipart/form-data"`, and the [`paramType`](#parameterParamType) MUST be `"form"`.
158 |
159 | ## 5. Schema
160 |
161 | ### 5.1 Resource Listing
162 |
163 | The Resource Listing serves as the root document for the API description. It contains general information about the API and an inventory of the available resources.
164 |
165 | By default, this document SHOULD be served at the `/api-docs` path.
166 |
167 | Field Name | Type | Description
168 | ---|:---:|---
169 | swaggerVersion | `string` | **Required.** Specifies the Swagger Specification version being used. It can be used by the Swagger UI and other clients to interpret the API listing. The value MUST be an existing Swagger specification version.
Currently, `"1.0"`, `"1.1"`, `"1.2"` are valid values. The field is a `string` type for possible non-numeric versions in the future (for example, "1.2a").
170 | apis | [ [Resource Object](#512-resource-object) ] | **Required.** Lists the resources to be described by this specification implementation. The array can have 0 or more elements.
171 | apiVersion| `string` | Provides the version of the application API (not to be confused by the [specification version](#rlSwaggerVersion)).
172 | info | [Info Object](#513-info-object) | Provides metadata about the API. The metadata can be used by the clients if needed, and can be presented in the Swagger-UI for convenience.
173 | authorizations | [Authorizations Object](#514-authorizations-object) | Provides information about the authorization schemes allowed on this API.
174 |
175 | #### 5.1.1 Object Example
176 |
177 | ```js
178 | {
179 | "apiVersion": "1.0.0",
180 | "swaggerVersion": "1.2",
181 | "apis": [
182 | {
183 | "path": "/pet",
184 | "description": "Operations about pets"
185 | },
186 | {
187 | "path": "/user",
188 | "description": "Operations about user"
189 | },
190 | {
191 | "path": "/store",
192 | "description": "Operations about store"
193 | }
194 | ],
195 | "authorizations": {
196 | "oauth2": {
197 | "type": "oauth2",
198 | "scopes": [
199 | {
200 | "scope": "email",
201 | "description": "Access to your email address"
202 | },
203 | {
204 | "scope": "pets",
205 | "description": "Access to your pets"
206 | }
207 | ],
208 | "grantTypes": {
209 | "implicit": {
210 | "loginEndpoint": {
211 | "url": "http://petstore.swagger.wordnik.com/oauth/dialog"
212 | },
213 | "tokenName": "access_token"
214 | },
215 | "authorization_code": {
216 | "tokenRequestEndpoint": {
217 | "url": "http://petstore.swagger.wordnik.com/oauth/requestToken",
218 | "clientIdName": "client_id",
219 | "clientSecretName": "client_secret"
220 | },
221 | "tokenEndpoint": {
222 | "url": "http://petstore.swagger.wordnik.com/oauth/token",
223 | "tokenName": "access_code"
224 | }
225 | }
226 | }
227 | }
228 | },
229 | "info": {
230 | "title": "Swagger Sample App",
231 | "description": "This is a sample server Petstore server. You can find out more about Swagger \n at http://swagger.wordnik.com or on irc.freenode.net, #swagger. For this sample,\n you can use the api key \"special-key\" to test the authorization filters",
232 | "termsOfServiceUrl": "http://swagger.io/terms/",
233 | "contact": "apiteam@wordnik.com",
234 | "license": "Apache 2.0",
235 | "licenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.html"
236 | }
237 | }
238 | ```
239 |
240 | #### 5.1.2 Resource Object
241 | The Resource object describes a [resource](#definitionResource) API endpoint in the application.
242 |
243 | Field Name | Type | Description
244 | ---|:---:|---
245 | path | `string` | **Required.** A relative path to the [API declaration](#52-api-declaration) from the path used to retrieve this Resource Listing. This `path` does not necessarily have to correspond to the URL which actually serves this resource in the API but rather where the resource listing itself is served. The value SHOULD be in a relative (URL) path format.
246 | description | `string` | *Recommended.* A short description of the resource.
247 |
248 | ##### 5.1.2.1 Object Example:
249 |
250 | ```js
251 | {
252 | "path": "/pets",
253 | "description": "Operations about pets."
254 | }
255 | ```
256 |
257 | #### 5.1.3 Info Object
258 | The object provides metadata about the API. The metadata can be used by the clients if needed, and can be presented in the Swagger-UI for convenience.
259 |
260 | Field Name | Type | Description
261 | ---|:---:|---
262 | title | `string` | **Required.** The title of the application.
263 | description | `string` | **Required.** A short description of the application.
264 | termsOfServiceUrl | `string` | A URL to the Terms of Service of the API.
265 | contact | `string` | An email to be used for API-related correspondence.
266 | license | `string` | The license name used for the API.
267 | licenseUrl | `string` | A URL to the license used for the API.
268 |
269 | ##### 5.1.3.1 Object Example:
270 |
271 | ```js
272 | {
273 | "title": "Swagger Sample App",
274 | "description": "This is a sample server Petstore server.",
275 | "termsOfServiceUrl": "http://swagger.io/terms/",
276 | "contact": "apiteam@wordnik.com",
277 | "license": "Apache 2.0",
278 | "licenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.html"
279 | }
280 | ```
281 |
282 | #### 5.1.4 Authorizations Object
283 | The object provides information about the authorization schemes provided on this API.
284 | Currently, Swagger supports three authorization schemes - basic authentication, API key and OAuth2.
285 | The Authorizations Object is used only to *declare* the available authorization schemes but not say which are required where.
286 | The actual authorization restrictions are done at the [API declaration](#52-api-declaration) level.
287 |
288 | Please note that the Authorizations Object is an object containing other object definitions and as such is structured as follows:
289 | ```js
290 | {
291 | "Authorization1" : {...},
292 | "Authorization2" : {...},
293 | ...,
294 | "AuthorizationN" : {...}
295 | }
296 | ```
297 |
298 | Field Name | Type | Description
299 | ---|:---:|---
300 | {Authorization Name} | [Authorization Object](#515-authorization-object) | A new authorization definition. The name given to the {Authorization Name} is a friendly name that should be used when referring to the authorization scheme. In many cases, the {Authorization Name} used is the same as its type, but it can be anything.
301 |
302 | ##### 5.1.4.1 Object Example:
303 | ```js
304 | {
305 | "oauth2": {
306 | "type": "oauth2",
307 | "scopes": [
308 | {
309 | "scope": "email",
310 | "description": "Access to your email address"
311 | },
312 | {
313 | "scope": "pets",
314 | "description": "Access to your pets"
315 | }
316 | ],
317 | "grantTypes": {
318 | "implicit": {
319 | "loginEndpoint": {
320 | "url": "http://petstore.swagger.wordnik.com/oauth/dialog"
321 | },
322 | "tokenName": "access_token"
323 | },
324 | "authorization_code": {
325 | "tokenRequestEndpoint": {
326 | "url": "http://petstore.swagger.wordnik.com/oauth/requestToken",
327 | "clientIdName": "client_id",
328 | "clientSecretName": "client_secret"
329 | },
330 | "tokenEndpoint": {
331 | "url": "http://petstore.swagger.wordnik.com/oauth/token",
332 | "tokenName": "access_code"
333 | }
334 | }
335 | }
336 | }
337 | }
338 | ```
339 |
340 | #### 5.1.5 Authorization Object
341 | The object provides information about a specific authorization scheme. Currently, the authorization schemes supported are basic authentication, API key and OAuth2.
342 |
343 | Within OAuth2, the Authorization Code Grant and Implicit Grant are supported.
344 |
345 | In the table below, the `Validity` column imposes additional limitations to the requirement of the [`type`](#authorizationType) in order to be able to use that field.
346 |
347 | Field Name | Type | Validity | Description
348 | ---|:---:|---|---
349 | type | `string` | Any | **Required.** The type of the authorization scheme. Values MUST be either `"basicAuth"`, `"apiKey"` or `"oauth2"`.
350 | passAs | `string` | `apiKey` | **Required.** Denotes how the API key must be passed. Valid values are `"header"` or `"query"`.
351 | keyname | `string` | `apiKey` | **Required.** The name of the `header` or `query` parameter to be used when passing the API key.
352 | scopes | [[Scope Object](#516-scope-object)] | `oauth2` | A list of supported OAuth2 scopes.
353 | grantTypes | [Grant Types Object](#517-grant-types-object) | `oauth2` | **Required.** Detailed information about the grant types supported by the OAuth2 authorization scheme.
354 |
355 | ##### 5.1.5.1 Object Example:
356 | ```js
357 | "oauth2": {
358 | "type": "oauth2",
359 | "scopes": [
360 | {
361 | "scope": "email",
362 | "description": "Access to your email address"
363 | },
364 | {
365 | "scope": "pets",
366 | "description": "Access to your pets"
367 | }
368 | ],
369 | "grantTypes": {
370 | "implicit": {
371 | "loginEndpoint": {
372 | "url": "http://petstore.swagger.wordnik.com/oauth/dialog"
373 | },
374 | "tokenName": "access_token"
375 | },
376 | "authorization_code": {
377 | "tokenRequestEndpoint": {
378 | "url": "http://petstore.swagger.wordnik.com/oauth/requestToken",
379 | "clientIdName": "client_id",
380 | "clientSecretName": "client_secret"
381 | },
382 | "tokenEndpoint": {
383 | "url": "http://petstore.swagger.wordnik.com/oauth/token",
384 | "tokenName": "access_code"
385 | }
386 | }
387 | }
388 | }
389 | ```
390 |
391 | #### 5.1.6 Scope Object
392 | Describes an OAuth2 authorization scope.
393 |
394 | Field Name | Type | Description
395 | ---|:---:|---
396 | scope | `string` | **Required.** The name of the scope.
397 | description | `string` | *Recommended.* A short description of the scope.
398 |
399 | ##### 5.1.6.1 Object Example:
400 | ```js
401 | {
402 | "scope": "email",
403 | "description": "Access to your email address"
404 | }
405 | ```
406 |
407 | #### 5.1.7 Grant Types Object
408 | Provides details regarding the OAuth2 grant types that are supported by the API. Currently, the Authorization Code and Implicit grants are supported.
409 |
410 | At least one of the grant types MUST be included (otherwise there's no need for the OAuth2 declaration).
411 |
412 | Field Name | Type | Description
413 | ---|:---:|---
414 | implicit | [Implicit Object](#518-implicit-object) | The Implicit Grant flow definition.
415 | authorization_code | [Authorization Code Object](#519-authorization-code-object) | The Authorization Code Grant flow definition.
416 |
417 | ##### 5.1.7.1 Object Example:
418 | ```js
419 | {
420 | "implicit": {
421 | "loginEndpoint": {
422 | "url": "http://petstore.swagger.wordnik.com/oauth/dialog"
423 | },
424 | "tokenName": "access_token"
425 | },
426 | "authorization_code": {
427 | "tokenRequestEndpoint": {
428 | "url": "http://petstore.swagger.wordnik.com/oauth/requestToken",
429 | "clientIdName": "client_id",
430 | "clientSecretName": "client_secret"
431 | },
432 | "tokenEndpoint": {
433 | "url": "http://petstore.swagger.wordnik.com/oauth/token",
434 | "tokenName": "access_code"
435 | }
436 | }
437 | }
438 | ```
439 |
440 | #### 5.1.8 Implicit Object
441 | Provides details regarding the OAuth2's Implicit Grant flow type.
442 |
443 | Field Name | Type | Description
444 | ---|:---:|---
445 | loginEndpoint | [Login Endpoint Object](#5110-login-endpoint-object) | **Required.** The login endpoint definition.
446 | tokenName | `string` | An optional alternative name to standard "access_token" OAuth2 parameter.
447 |
448 | ##### 5.1.8.1 Object Example:
449 | ```js
450 | {
451 | "loginEndpoint": {
452 | "url": "http://petstore.swagger.wordnik.com/oauth/dialog"
453 | },
454 | "tokenName": "access_token"
455 | }
456 | ```
457 |
458 | #### 5.1.9 Authorization Code Object
459 | Provides details regarding the OAuth2's Authorization Code Grant flow type.
460 |
461 | Field Name | Type | Description
462 | ---|:---:|---
463 | tokenRequestEndpoint | [Token Request Endpoint Object](#5111-token-request-endpoint-object) | **Required.** The token request endpoint definition.
464 | tokenEndpoint | [Token Endpoint Object](#5112-token-endpoint-object) | **Required.** The token endpoint definition.
465 |
466 | ##### 5.1.9.1 Object Example:
467 | ```js
468 | {
469 | "tokenRequestEndpoint": {
470 | "url": "http://petstore.swagger.wordnik.com/oauth/requestToken",
471 | "clientIdName": "client_id",
472 | "clientSecretName": "client_secret"
473 | },
474 | "tokenEndpoint": {
475 | "url": "http://petstore.swagger.wordnik.com/oauth/token",
476 | "tokenName": "access_code"
477 | }
478 | }
479 | ```
480 |
481 | #### 5.1.10 Login Endpoint Object
482 | Provides details regarding the Implicit Grant's *authorization endpoint*.
483 |
484 | Field Name | Type | Description
485 | ---|:---:|---
486 | url | `string` | **Required.** The URL of the authorization endpoint for the implicit grant flow. The value SHOULD be in a URL format.
487 |
488 | ##### 5.1.10.1 Object Example:
489 | ```js
490 | {
491 | "url": "http://petstore.swagger.wordnik.com/oauth/dialog"
492 | }
493 | ```
494 |
495 | #### 5.1.11 Token Request Endpoint Object
496 | Provides details regarding the OAuth2's *Authorization Endpoint*.
497 |
498 | Field Name | Type | Description
499 | ---|:---:|---
500 | url | `string` | **Required.** The URL of the authorization endpoint for the authentication code grant flow. The value SHOULD be in a URL format.
501 | clientIdName | `string` | An optional alternative name to standard "client_id" OAuth2 parameter.
502 | clientSecretName | `string` | An optional alternative name to the standard "client_secret" OAuth2 parameter.
503 |
504 | ##### 5.1.11.1 Object Example:
505 | ```js
506 | {
507 | "url": "http://petstore.swagger.wordnik.com/oauth/requestToken",
508 | "clientIdName": "client_id",
509 | "clientSecretName": "client_secret"
510 | }
511 | ```
512 |
513 | #### 5.1.12 Token Endpoint Object
514 | Provides details regarding the OAuth2's *Token Endpoint*.
515 |
516 | Field Name | Type | Description
517 | ---|:---:|---
518 | url | `string` | **Required.** The URL of the token endpoint for the authentication code grant flow. The value SHOULD be in a URL format.
519 | tokenName | `string` | An optional alternative name to standard "access_token" OAuth2 parameter.
520 |
521 | ##### 5.1.12.1 Object Example:
522 | ```js
523 | {
524 | "url": "http://petstore.swagger.wordnik.com/oauth/token",
525 | "tokenName": "access_code"
526 | }
527 | ```
528 |
529 | ### 5.2 API Declaration
530 |
531 | The API Declaration provides information about an API exposed on a resource. There should be one file per [Resource](#512-resource-object) described. The file MUST be served in the URL described by the [`path`](#aePath) field.
532 |
533 | Field Name | Type | Description
534 | ---|:---:|---
535 | swaggerVersion | `string` | **Required.** Specifies the Swagger Specification version being used. It can be used by the Swagger UI and other clients to interpret the API listing. The value MUST be an existing Swagger specification version.
Currently, `"1.0"`, `"1.1"`, `"1.2"` are valid values.
536 | apiVersion | `string` | Provides the version of the application API (not to be confused by the [specification version](#adSwaggerVersion)).
537 | basePath | `string` | **Required.** The root URL serving the API. This field is important because while it is common to have the Resource Listing and API Declarations on the server providing the APIs themselves, it is not a requirement. The API specifications can be served using static files and not generated by the API server itself, so the URL for serving the API cannot always be derived from the URL serving the API specification. The value SHOULD be in the format of a URL.
538 | resourcePath | `string` | The *relative* path to the resource, from the [`basePath`](#adBasePath), which this API Specification describes. The value MUST precede with a forward slash (`"/"`).
539 | apis | [[API Object](#522-api-object)] | **Required.** A list of the APIs exposed on this resource. There MUST NOT be more than one API Object per [`path`](#apiPath) in the array.
540 | models | [Models Object](#526-models-object) | A list of the models available to this resource. Note that these need to be exposed separately for each API Declaration.
541 | produces | [`string`] | A list of MIME types the APIs on this resource can produce. This is global to all APIs but can be overridden on specific API calls.
542 | consumes | [`string`] | A list of MIME types the APIs on this resource can consume. This is global to all APIs but can be overridden on specific API calls.
543 | authorizations | [Authorizations Object](#5210-authorizations-object) | A list of authorizations schemes *required* for the operations listed in this API declaration. Individual operations may override this setting. If there are multiple authorization schemes described here, it means they're **all** applied.
544 |
545 | #### 5.2.1 Object Example
546 | ```js
547 | {
548 | "apiVersion": "1.0.0",
549 | "swaggerVersion": "1.2",
550 | "basePath": "http://petstore.swagger.wordnik.com/api",
551 | "resourcePath": "/store",
552 | "produces": [
553 | "application/json"
554 | ],
555 | "authorizations": {},
556 | "apis": [
557 | {
558 | "path": "/store/order/{orderId}",
559 | "operations": [
560 | {
561 | "method": "GET",
562 | "summary": "Find purchase order by ID",
563 | "notes": "For valid response try integer IDs with value <= 5. Anything above 5 or nonintegers will generate API errors",
564 | "type": "Order",
565 | "nickname": "getOrderById",
566 | "authorizations": {},
567 | "parameters": [
568 | {
569 | "name": "orderId",
570 | "description": "ID of pet that needs to be fetched",
571 | "required": true,
572 | "type": "string",
573 | "paramType": "path"
574 | }
575 | ],
576 | "responseMessages": [
577 | {
578 | "code": 400,
579 | "message": "Invalid ID supplied"
580 | },
581 | {
582 | "code": 404,
583 | "message": "Order not found"
584 | }
585 | ]
586 | },
587 | {
588 | "method": "DELETE",
589 | "summary": "Delete purchase order by ID",
590 | "notes": "For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors",
591 | "type": "void",
592 | "nickname": "deleteOrder",
593 | "authorizations": {
594 | "oauth2": [
595 | {
596 | "scope": "test:anything",
597 | "description": "anything"
598 | }
599 | ]
600 | },
601 | "parameters": [
602 | {
603 | "name": "orderId",
604 | "description": "ID of the order that needs to be deleted",
605 | "required": true,
606 | "type": "string",
607 | "paramType": "path"
608 | }
609 | ],
610 | "responseMessages": [
611 | {
612 | "code": 400,
613 | "message": "Invalid ID supplied"
614 | },
615 | {
616 | "code": 404,
617 | "message": "Order not found"
618 | }
619 | ]
620 | }
621 | ]
622 | },
623 | {
624 | "path": "/store/order",
625 | "operations": [
626 | {
627 | "method": "POST",
628 | "summary": "Place an order for a pet",
629 | "notes": "",
630 | "type": "void",
631 | "nickname": "placeOrder",
632 | "authorizations": {
633 | "oauth2": [
634 | {
635 | "scope": "test:anything",
636 | "description": "anything"
637 | }
638 | ]
639 | },
640 | "parameters": [
641 | {
642 | "name": "body",
643 | "description": "order placed for purchasing the pet",
644 | "required": true,
645 | "type": "Order",
646 | "paramType": "body"
647 | }
648 | ],
649 | "responseMessages": [
650 | {
651 | "code": 400,
652 | "message": "Invalid order"
653 | }
654 | ]
655 | }
656 | ]
657 | }
658 | ],
659 | "models": {
660 | "Order": {
661 | "id": "Order",
662 | "properties": {
663 | "id": {
664 | "type": "integer",
665 | "format": "int64"
666 | },
667 | "petId": {
668 | "type": "integer",
669 | "format": "int64"
670 | },
671 | "quantity": {
672 | "type": "integer",
673 | "format": "int32"
674 | },
675 | "status": {
676 | "type": "string",
677 | "description": "Order Status",
678 | "enum": [
679 | "placed",
680 | "approved",
681 | "delivered"
682 | ]
683 | },
684 | "shipDate": {
685 | "type": "string",
686 | "format": "date-time"
687 | }
688 | }
689 | }
690 | }
691 | }
692 | ```
693 |
694 | #### 5.2.2 API Object
695 | The API Object describes one or more operations on a single [`path`](#apiPath). In the [`apis`](#adApis) array, there MUST be only one [`API Object`](#522-api-object) per [`path`](#apiPath).
696 |
697 | Field Name | Type | Description
698 | ---|:---:|---
699 | path | `string` | **Required.** The relative path to the operation, from the [`basePath`](#adBasePath), which this operation describes. The value SHOULD be in a relative (URL) path format.
700 | description | `string` | *Recommended.* A short description of the resource.
701 | operations | [[Operation Object](#523-operation-object)] | **Required.** A list of the API operations available on this path. The array may include 0 or more operations. There MUST NOT be more than one Operation Object per [`method`](#operationMethod) in the array.
702 |
703 | ##### 5.2.2.1 Object Example:
704 |
705 | ```js
706 | {
707 | "path": "/pet",
708 | "operations": [
709 | {
710 | "method": "PUT",
711 | "summary": "Update an existing pet",
712 | "notes": "",
713 | "type": "void",
714 | "nickname": "updatePet",
715 | "authorizations": {},
716 | "parameters": [
717 | {
718 | "name": "body",
719 | "description": "Pet object that needs to be updated in the store",
720 | "required": true,
721 | "type": "Pet",
722 | "paramType": "body"
723 | }
724 | ],
725 | "responseMessages": [
726 | {
727 | "code": 400,
728 | "message": "Invalid ID supplied"
729 | },
730 | {
731 | "code": 404,
732 | "message": "Pet not found"
733 | },
734 | {
735 | "code": 405,
736 | "message": "Validation exception"
737 | }
738 | ]
739 | },
740 | {
741 | "method": "POST",
742 | "summary": "Add a new pet to the store",
743 | "notes": "",
744 | "type": "void",
745 | "nickname": "addPet",
746 | "consumes": [
747 | "application/json",
748 | "application/xml"
749 | ],
750 | "authorizations": {
751 | "oauth2": [
752 | {
753 | "scope": "test:anything",
754 | "description": "anything"
755 | }
756 | ]
757 | },
758 | "parameters": [
759 | {
760 | "name": "body",
761 | "description": "Pet object that needs to be added to the store",
762 | "required": true,
763 | "type": "Pet",
764 | "paramType": "body"
765 | }
766 | ],
767 | "responseMessages": [
768 | {
769 | "code": 405,
770 | "message": "Invalid input"
771 | }
772 | ]
773 | }
774 | ]
775 | }
776 | ```
777 |
778 | #### 5.2.3 Operation Object
779 | The Operation Object describes a single operation on a [`path`](#apiPath).
780 |
781 | In the [`operations`](#apiOperations) array, there MUST be only one [`Operation Object`](#523-operation-object) per [`method`](#operationMethod).
782 |
783 | This object includes the [Data Type Fields](#433-data-type-fields) in order to describe the return value of the operation. The [`type`](#dataTypeType) field MUST be used to link to other models.
784 |
785 | This is the only object where the [`type`](#dataTypeType) MAY have the value of [`void`](#432-void) to indicate that the operation returns no value.
786 |
787 | Field Name | Type | Description
788 | ---|:---:|---
789 | method | `string` | **Required.** The HTTP method required to invoke this operation. The value MUST be one of the following values: `"GET"`, `"HEAD"`, `"POST"`, `"PUT"`, `"PATCH"`, `"DELETE"`, `"OPTIONS"`. The values MUST be in uppercase.
790 | summary | `string` | A short summary of what the operation does. For maximum readability in the swagger-ui, this field SHOULD be less than 120 characters.
791 | notes | `string` | A verbose explanation of the operation behavior.
792 | nickname |`string` | **Required.** A unique id for the operation that can be used by tools reading the output for further and easier manipulation. For example, Swagger-Codegen will use the nickname as the method name of the operation in the client it generates. The value MUST be alphanumeric and may include underscores. Whitespace characters are not allowed.
793 | authorizations | [Authorizations Object](#5210-authorizations-object) | A list of authorizations required to execute this operation. While not mandatory, if used, it overrides the value given at the API Declaration's [authorizations](#adAuthorizations). In order to completely remove API Declaration's authorizations completely, an empty object (`{}`) may be applied.
794 | parameters | [[Parameter Object](#524-parameter-object)] | **Required.** The inputs to the operation. If no parameters are needed, an empty array MUST be included.
795 | responseMessages | [[Response Message Object](#525-response-message-object)] | Lists the possible response statuses that can return from the operation.
796 | produces | [`string`] | A list of MIME types this operation can produce. This is overrides the global [`produces`](#adProduces) definition at the root of the API Declaration. Each `string` value SHOULD represent a MIME type.
797 | consumes | [`string`] | A list of MIME types this operation can consume. This is overrides the global [`consumes`](#adConsumes) definition at the root of the API Declaration. Each `string` value SHOULD represent a MIME type.
798 | deprecated | `string` | Declares this operation to be deprecated. Usage of the declared operation should be refrained. Valid value MUST be either `"true"` or `"false"`. *Note:* This field will change to type `boolean` in the future.
799 |
800 | ##### 5.2.3.1 Object Example
801 |
802 | ````js
803 | {
804 | "method": "GET",
805 | "summary": "Find pet by ID",
806 | "notes": "Returns a pet based on ID",
807 | "type": "Pet",
808 | "nickname": "getPetById",
809 | "authorizations": {},
810 | "parameters": [
811 | {
812 | "name": "petId",
813 | "description": "ID of pet that needs to be fetched",
814 | "required": true,
815 | "type": "integer",
816 | "format": "int64",
817 | "paramType": "path",
818 | "minimum": "1.0",
819 | "maximum": "100000.0"
820 | }
821 | ],
822 | "responseMessages": [
823 | {
824 | "code": 400,
825 | "message": "Invalid ID supplied"
826 | },
827 | {
828 | "code": 404,
829 | "message": "Pet not found"
830 | }
831 | ]
832 | }
833 | ````
834 |
835 | #### 5.2.4 Parameter Object
836 |
837 | The Parameter Object describes a single parameter to be sent in an operation and maps to the [`parameters`](#operationParameters) field in the [Operation Object](#523-operation-object).
838 |
839 | This object includes the [Data Type Fields](#433-data-type-fields) in order to describe the type of this parameter. The [`type`](#dataTypeType) field MUST be used to link to other models.
840 |
841 | If [`type`](#dataTypeType) is [`File`](#434-file), the [`consumes`](#operationConsumes) field MUST be `"multipart/form-data"`, and the [`paramType`](#parameterParamType) MUST be `"form"`.
842 |
843 | Field Name | Type | Description
844 | ---|:---:|---
845 | paramType | `string` | **Required.** The type of the parameter (that is, the location of the parameter in the request). The value MUST be one of these values: `"path"`, `"query"`, `"body"`, `"header"`, `"form"`. Note that the values MUST be lower case.
846 | name | `string` | **Required.** The unique name for the parameter. Each `name` MUST be unique, even if they are associated with different `paramType` values. Parameter names are *case sensitive*. - If [`paramType`](#parameterParamType) is `"path"`, the `name` field MUST correspond to the associated path segment from the [`path`](#apiPath) field in the [API Object](#522-api-object).
- If [`paramType`](#parameterParamType) is `"query"`, the `name` field corresponds to the query parameter name.
- If [`paramType`](#parameterParamType) is `"body"`, the name is used only for Swagger-UI and Swagger-Codegen. In this case, the `name` MUST be `"body"`.
- If [`paramType`](#parameterParamType) is `"form"`, the `name` field corresponds to the form parameter key.
- If [`paramType`](#parameterParamType) is `"header"`, the `name` field corresponds to the header parameter key.
See [here](#5241-name-examples) for some examples.
847 | description | `string` | *Recommended.* A brief description of this parameter.
848 | required | `boolean` | A flag to note whether this parameter is required. If this field is not included, it is equivalent to adding this field with the value `false`. If [`paramType`](#parameterParamType) is `"path"` then this field MUST be included and have the value `true`.
849 | allowMultiple | `boolean` | Another way to allow multiple values for a "query" parameter. If used, the query parameter may accept comma-separated values. The field may be used only if [`paramType`](#parameterParamType) is `"query"`, `"header"` or `"path"`.
850 |
851 | ##### 5.2.4.1 Name Examples
852 | - If [`paramType`](#parameterParamType) is `"path"`, and assuming the `path` is `"/pet/{id}"`:
853 |
854 | ```js
855 | "name": "id"
856 | ```
857 |
858 | - If [`paramType`](#parameterParamType) is `"query"`, and assuming the URL call is `"http://host/resource?limit=100"` (that is, there's a query parameter called `"limit"`):
859 |
860 | ```js
861 | "name": "limit"
862 | ```
863 |
864 | - If [`paramType`](#parameterParamType) is `"body"`:
865 |
866 | ```js
867 | "name": "body"
868 | ```
869 |
870 | ##### 5.2.4.2 Object Example
871 |
872 | ```js
873 | {
874 | "name": "body",
875 | "description": "Pet object that needs to be updated in the store",
876 | "required": true,
877 | "type": "Pet",
878 | "paramType": "body"
879 | }
880 | ```
881 |
882 | #### 5.2.5 Response Message Object
883 |
884 | The Response Message Object describes a single possible response message that can be returned from the operation call, and maps to the [`responseMessages`](#operationResponseMessages) field in the [Operation Object](#523-operation-object). Each Response Message allows you to give further details as to why the HTTP status code may be received.
885 |
886 | Field Name | Type | Description |
887 | ---|:---:|---
888 | code | `integer` | **Required.** The HTTP status code returned. The value SHOULD be one of the status codes as described in [RFC 2616 - Section 10](http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html).
889 | message | `string` | **Required.** The explanation for the status code. It SHOULD be the reason an error is received if an error status code is used.
890 | responseModel | `string` | The return type for the given response.
891 |
892 | ##### 5.2.5.1 Object Example
893 |
894 | ```js
895 | {
896 | "code": 404,
897 | "message": "no project found",
898 | "responseModel": "ErrorModel"
899 | }
900 | ```
901 |
902 | #### 5.2.6 Models Object
903 |
904 | The Models Object holds a field per model definition, and this is different than the structure of the other objects in the spec. It follows a subset of the [JSON-Schema](http://json-schema.org/) specification.
905 |
906 | Please note that the Models Object is an object containing other object definitions and as such is structured as follows:
907 | ```js
908 | {
909 | "Model1" : {...},
910 | "Model2" : {...},
911 | ...,
912 | "ModelN" : {...}
913 | }
914 | ```
915 |
916 | Field Name | Type | Description
917 | ---|:---:|---
918 | {Model Name} | [Model Object](#527-model-object) | A new model definition. Note the actual name of the field is the name you're giving your model. For example, "Category", "Pet", "User".
919 |
920 | ##### 5.2.6.1 Object Example
921 |
922 | ```js
923 | {
924 | "Category": {
925 | "id": "Category",
926 | "properties": {
927 | "id": {
928 | "type": "integer",
929 | "format": "int64"
930 | },
931 | "name": {
932 | "type": "string"
933 | }
934 | }
935 | }
936 | }
937 | ```
938 |
939 | #### 5.2.7 Model Object
940 |
941 | A Model Object holds the definition of a new model for this API Declaration.
942 |
943 | Models in Swagger allow for inheritance. The inheritance is controlled by two fields - [`subTypes`](#modelSubTypes) to give the name of the models extending this definition, and [`discriminator`](#modelDiscriminator) to support polymorphism.
944 |
945 | Field Name | Type | Description
946 | ---|:---:|---
947 | id | `string` | **Required.** A unique identifier for the model. This MUST be the name given to [{Model Name}](#modelsModelname).
948 | description | `string` | A brief description of this model.
949 | required | [`string`] | A definition of which properties MUST exist when a model instance is produced. The values MUST be the [`{Property Name}`](#propertiesPropertyName) of one of the [`properties`](#528-properties-object).
950 | properties | [Properties Object](#528-properties-object) | **Required.** A list of properties (fields) that are part of the model
951 | subTypes | [`string`] | List of the [model `id`s](#modelId) that inherit from this model. Sub models inherit all the properties of the parent model. Since inheritance is transitive, if the parent of a model inherits from another model, its sub-model will include all properties. As such, if you have `Foo->Bar->Baz`, then Baz will inherit the properties of Bar and Foo. There MUST NOT be a cyclic definition of inheritance. For example, if `Foo -> ... -> Bar`, having `Bar -> ... -> Foo` is not allowed. There also MUST NOT be a case of multiple inheritance. For example, `Foo -> Baz <- Bar` is not allowed. A sub-model definition MUST NOT override the [`properties`](#modelProperties) of any of its ancestors. All sub-models MUST be defined in the same [API Declaration](#52-api-declaration).
952 | discriminator | `string` | MUST be included only if [`subTypes`](#modelSubTypes) is included. This field allows for polymorphism within the described inherited models. This field MAY be included at any base model but MUST NOT be included in a sub-model. The value of this field MUST be a name of one of the [`properties`](#modelProperties) in this model, and that field MUST be in the [`required`](#modelRequired) list. When used, the value of the *discriminator property* MUST be the name of the parent model or any of its sub-models (to any depth of inheritance).
953 |
954 | ##### 5.2.7.1 Object Example
955 |
956 | ```js
957 | {
958 | "id": "Order",
959 | "properties": {
960 | "id": {
961 | "type": "integer",
962 | "format": "int64"
963 | },
964 | "petId": {
965 | "type": "integer",
966 | "format": "int64"
967 | },
968 | "quantity": {
969 | "type": "integer",
970 | "format": "int32"
971 | },
972 | "status": {
973 | "type": "string",
974 | "description": "OrderStatus",
975 | "enum": [
976 | "placed",
977 | "approved",
978 | "delivered"
979 | ]
980 | },
981 | "shipDate": {
982 | "type": "string",
983 | "format": "date-time"
984 | }
985 | }
986 | }
987 | ```
988 |
989 | ##### 5.2.7.2 Inheritance Example
990 |
991 | Say we have a general Animal model, and a sub-model for Cat.
992 |
993 | ```js
994 | "Animal": {
995 | "id": "Animal",
996 | "required": [
997 | "id",
998 | "type"
999 | ],
1000 | "properties": {
1001 | "id": {
1002 | "type": "long"
1003 | },
1004 | "type": {
1005 | "type": "string"
1006 | }
1007 | },
1008 | "subTypes": ["Cat"],
1009 | "discriminator": "type"
1010 | },
1011 | "Cat": {
1012 | "id": "Cat",
1013 | "required": [
1014 | "likesMilk"
1015 | ],
1016 | "properties": {
1017 | "likesMilk": {
1018 | "type": "boolean"
1019 | }
1020 | },
1021 | }
1022 | ```
1023 |
1024 | #### 5.2.8 Properties Object
1025 |
1026 | The Properties Object holds a field per property definition, and this is different than the structure of the other objects in the spec. It follows a subset of the [JSON-Schema](http://json-schema.org/) specification.
1027 |
1028 | Please note that the Properties Object is an object containing other object definitions and as such is structured as follows:
1029 | ```js
1030 | {
1031 | "Property1" : {...},
1032 | "Property2" : {...},
1033 | ...,
1034 | "PropertyN" : {...}
1035 | }
1036 | ```
1037 |
1038 | Field Name | Type | Description
1039 | ---|:---:|---
1040 | {Property Name} | [Property Object](#529-property-object) | A new model property definition. Note the actual name of the field is the name you're giving your property. For example, "id", "name", "age".
1041 |
1042 | ##### 5.2.8.1 Object Example
1043 | ```js
1044 | {
1045 | "id": {
1046 | "type": "integer",
1047 | "format": "int64"
1048 | },
1049 | "name": {
1050 | "type": "string"
1051 | }
1052 | }
1053 | ```
1054 |
1055 | #### 5.2.9 Property Object
1056 |
1057 | A Property Object holds the definition of a new property for a model.
1058 |
1059 | This object includes the [Data Type Fields](#433-data-type-fields) in order to describe the type of this property. The [`$ref`](#dataTypeRef) field MUST be used when linking to other models.
1060 |
1061 | Properties MUST NOT contain other properties. If there's a need for an internal object hierarchy, additional models MUST be created and linked to a flat structure.
1062 |
1063 | Field Name | Type | Description
1064 | ---|:---:|---
1065 | description | `string` | *Recommended.* A brief description of this property.
1066 |
1067 | ##### 5.2.9.1 Object Examples
1068 |
1069 | A simple 64bit integer field called "id", with a description and min/max values:
1070 |
1071 | ```js
1072 | "id": {
1073 | "type": "integer",
1074 | "format": "int64",
1075 | "description": "unique identifier for the pet",
1076 | "minimum": "0.0",
1077 | "maximum": "100.0"
1078 | }
1079 | ```
1080 |
1081 | A "category" field of a Category model.
1082 |
1083 | ```js
1084 | "category": {
1085 | "$ref": "Category"
1086 | }
1087 | ```
1088 |
1089 | A "tags" field of type array containing Tag models.
1090 |
1091 | ```js
1092 | "tags": {
1093 | "type": "array",
1094 | "items": {
1095 | "$ref": "Tag"
1096 | }
1097 | }
1098 | ```
1099 |
1100 | #### 5.2.10 Authorizations Object
1101 | The Authorizations Object provides information about the authorization schemes enforced on this API. If used in the API Declaration's [authorizations](#adAuthorizations), it applies to all operations listed. If used in the Operation's [authorizations](#operationAuthorizations), it applies to the operation itself and may override the API Declaration's authorizations.
1102 | If multiple authorization schemes are described, they are **all** required to perform the operations listed.
1103 |
1104 | Please note that the Authorizations Object is an object containing arrays of object definitions and as such is structured as follows:
1105 | ```js
1106 | {
1107 | "Authorization1" : [...],
1108 | "Authorization2" : [...],
1109 | ...,
1110 | "AuthorizationN" : [...]
1111 | }
1112 | ```
1113 |
1114 | Field Name | Type | Description
1115 | ---|:---:|---
1116 | {Authorization Name} | * | The authorization scheme to be used. The name given to the {Authorization Name} MUST be a friendly name that was given to an authorization scheme in the Resource Listing's [authorizations](#rlAuthorizations). If the friendly name describes an OAuth2 security scheme, the value should be of type \[[Scope Object](#5211-scope-object)\] (but may be an empty array to denote 'no scopes'). For all other authorization scheme types, the value MUST be an empty array.
1117 |
1118 | ##### 5.2.10 Object Example:
1119 | ```js
1120 | {
1121 | "oauth2": [
1122 | {
1123 | "scope": "write:pets",
1124 | "description": "modify pets in your account"
1125 | },
1126 | {
1127 | "scope": "read:pets",
1128 | "description": "read your pets"
1129 | }
1130 | ]
1131 | }
1132 | ```
1133 |
1134 | #### 5.2.11 Scope Object
1135 | Describes an OAuth2 authorization scope. The scope described here MUST be described in the respective friendly name definition of the security scheme in the Resource Listing's [authorizations](#rlAuthorizations).
1136 |
1137 | Field Name | Type | Description
1138 | ---|:---:|---
1139 | scope | `string` | **Required.** The name of the scope.
1140 | description | `string` | *Recommended.* A short description of the scope.
1141 |
1142 | ##### 5.2.11.1 Object Example:
1143 | ```js
1144 | {
1145 | "scope": "email",
1146 | "description": "Access to your email address"
1147 | }
1148 | ```
1149 |
--------------------------------------------------------------------------------
/versions/2.0-editors.md:
--------------------------------------------------------------------------------
1 | ## Active
2 | * Jeremy Whitlock [@whitlockjc](https://github.com/whitlockjc)
3 | * Marsh Gardiner [@earth2marsh](https://github.com/earth2marsh)
4 | * Ron Ratovsky [@webron](https://github.com/webron)
5 | * Tony Tam [@fehguy](https://github.com/fehguy)
6 |
--------------------------------------------------------------------------------
/versions/3.0.0-editors.md:
--------------------------------------------------------------------------------
1 | ## Active
2 | * Jeremy Whitlock [@whitlockjc](https://github.com/whitlockjc)
3 | * Marsh Gardiner [@earth2marsh](https://github.com/earth2marsh)
4 | * Ron Ratovsky [@webron](https://github.com/webron)
5 | * Tony Tam [@fehguy](https://github.com/fehguy)
6 |
7 | ## Emeritus
8 | * Jason Harmon [@jharmn](https://github.com/jharmn)
9 |
--------------------------------------------------------------------------------
/versions/3.0.1-editors.md:
--------------------------------------------------------------------------------
1 | ## Active
2 | * Darrel Miller [@darrelmiller](https://github.com/darrelmiller)
3 | * Jeremy Whitlock [@whitlockjc](https://github.com/whitlockjc)
4 | * Marsh Gardiner [@earth2marsh](https://github.com/earth2marsh)
5 | * Ron Ratovsky [@webron](https://github.com/webron)
6 |
7 | ## Emeritus
8 | * Jason Harmon [@jharmn](https://github.com/jharmn)
9 | * Tony Tam [@fehguy](https://github.com/fehguy)
10 |
--------------------------------------------------------------------------------
/versions/3.0.2-editors.md:
--------------------------------------------------------------------------------
1 | ## Active
2 | * Darrel Miller [@darrelmiller](https://github.com/darrelmiller)
3 | * Jeremy Whitlock [@whitlockjc](https://github.com/whitlockjc)
4 | * Marsh Gardiner [@earth2marsh](https://github.com/earth2marsh)
5 | * Mike Ralphson [@MikeRalphson](https://github.com/MikeRalphson)
6 | * Ron Ratovsky [@webron](https://github.com/webron)
7 | * Uri Sarid [@usarid](https://github.com/usarid)
8 |
9 | ## Emeritus
10 | * Jason Harmon [@jharmn](https://github.com/jharmn)
11 | * Tony Tam [@fehguy](https://github.com/fehguy)
12 |
--------------------------------------------------------------------------------
/versions/3.0.3-editors.md:
--------------------------------------------------------------------------------
1 | ## Active
2 | * Darrel Miller [@darrelmiller](https://github.com/darrelmiller)
3 | * Jeremy Whitlock [@whitlockjc](https://github.com/whitlockjc)
4 | * Marsh Gardiner [@earth2marsh](https://github.com/earth2marsh)
5 | * Mike Ralphson [@MikeRalphson](https://github.com/MikeRalphson)
6 | * Ron Ratovsky [@webron](https://github.com/webron)
7 | * Uri Sarid [@usarid](https://github.com/usarid)
8 |
9 | ## Emeritus
10 | * Jason Harmon [@jharmn](https://github.com/jharmn)
11 | * Tony Tam [@fehguy](https://github.com/fehguy)
12 |
--------------------------------------------------------------------------------
/versions/3.0.4-editors.md:
--------------------------------------------------------------------------------
1 | # OpenAPI Specification Editors
2 |
3 | ## Active
4 | * Darrel Miller [@darrelmiller](https://github.com/darrelmiller)
5 | * Henry Andrews [@handrews](https://github.com/handrews)
6 | * Jeremy Whitlock [@whitlockjc](https://github.com/whitlockjc)
7 | * Lorna Mitchell [@lornajane](https://github.com/lornajane)
8 | * Marsh Gardiner [@earth2marsh](https://github.com/earth2marsh)
9 | * Miguel Quintero [@miqui](https://github.com/miqui)
10 | * Mike Kistler [@mikekistler](https://github.com/mikekistler)
11 | * Ralf Handl [@ralfhandl](https://github.com/ralfhandl)
12 | * Ron Ratovsky [@webron](https://github.com/webron)
13 |
14 | ## Emeritus
15 | * Mike Ralphson [@MikeRalphson](https://github.com/MikeRalphson)
16 | * Uri Sarid [@usarid](https://github.com/usarid)
17 | * Jason Harmon [@jharmn](https://github.com/jharmn)
18 | * Tony Tam [@fehguy](https://github.com/fehguy)
19 |
--------------------------------------------------------------------------------
/versions/3.1.0-editors.md:
--------------------------------------------------------------------------------
1 | ## Active
2 | * Darrel Miller [@darrelmiller](https://github.com/darrelmiller)
3 | * Jeremy Whitlock [@whitlockjc](https://github.com/whitlockjc)
4 | * Marsh Gardiner [@earth2marsh](https://github.com/earth2marsh)
5 | * Mike Ralphson [@MikeRalphson](https://github.com/MikeRalphson)
6 | * Ron Ratovsky [@webron](https://github.com/webron)
7 | * Uri Sarid [@usarid](https://github.com/usarid)
8 |
9 | ## Emeritus
10 | * Jason Harmon [@jharmn](https://github.com/jharmn)
11 | * Tony Tam [@fehguy](https://github.com/fehguy)
12 |
--------------------------------------------------------------------------------
/versions/3.1.1-editors.md:
--------------------------------------------------------------------------------
1 | # OpenAPI Specification Editors
2 |
3 | ## Active
4 | * Darrel Miller [@darrelmiller](https://github.com/darrelmiller)
5 | * Henry Andrews [@handrews](https://github.com/handrews)
6 | * Jeremy Whitlock [@whitlockjc](https://github.com/whitlockjc)
7 | * Lorna Mitchell [@lornajane](https://github.com/lornajane)
8 | * Marsh Gardiner [@earth2marsh](https://github.com/earth2marsh)
9 | * Miguel Quintero [@miqui](https://github.com/miqui)
10 | * Mike Kistler [@mikekistler](https://github.com/mikekistler)
11 | * Ralf Handl [@ralfhandl](https://github.com/ralfhandl)
12 | * Ron Ratovsky [@webron](https://github.com/webron)
13 |
14 | ## Emeritus
15 | * Mike Ralphson [@MikeRalphson](https://github.com/MikeRalphson)
16 | * Uri Sarid [@usarid](https://github.com/usarid)
17 | * Jason Harmon [@jharmn](https://github.com/jharmn)
18 | * Tony Tam [@fehguy](https://github.com/fehguy)
19 |
--------------------------------------------------------------------------------