├── .adr-dir
├── .github
├── ISSUE_TEMPLATE
│ └── config.yml
├── issue_template.md
└── workflows
│ └── jekyll-gh-pages.yml
├── .gitignore
├── LICENSE
├── README.md
├── doc
├── architecture
│ ├── README.md
│ └── decisions
│ │ ├── 0001-record-architecture-decisions.md
│ │ ├── 0002-support-for-iris.md
│ │ └── template.md
├── index.md
├── initial-proposals
│ ├── Deployments.md
│ ├── README.md
│ ├── changes.md
│ └── examples
│ │ ├── FlatOperations
│ │ └── OperationList.yaml
│ │ ├── aggregatedapi.yaml
│ │ ├── dependentParameters.yaml
│ │ ├── parameterSchema.yaml
│ │ ├── petstore.yaml
│ │ └── rpc.yaml
└── moonwalk.html
├── package-lock.json
├── package.json
├── scripts
└── Generate.ps1
└── specification
├── moonwalk-host.html
├── moonwalk-source.md
└── respecConfig.js
/.adr-dir:
--------------------------------------------------------------------------------
1 | doc/architecture/decisions
2 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: true
2 | contact_links:
3 | - name: Have an idea for Moonwalk?
4 | url: https://github.com/OAI/sig-moonwalk/discussions
5 | about: Please open or join a discussion instead of an issue!
6 | - name: Want to chat about Moonwalk?
7 | url: https://communityinviter.com/apps/open-api/openapi
8 | about: "Please join the #sig-moonwalk channel on our Slack!"
9 |
--------------------------------------------------------------------------------
/.github/issue_template.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: ''
3 | about: Consider opening a discussion instead...
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 |
17 |
--------------------------------------------------------------------------------
/.github/workflows/jekyll-gh-pages.yml:
--------------------------------------------------------------------------------
1 | # Sample workflow for building and deploying a Jekyll site to GitHub Pages
2 | name: Deploy Jekyll with GitHub Pages dependencies preinstalled
3 |
4 | on:
5 | # Runs on pushes targeting the default branch
6 | push:
7 | branches: ["main"]
8 |
9 | # Allows you to run this workflow manually from the Actions tab
10 | workflow_dispatch:
11 |
12 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
13 | permissions:
14 | contents: read
15 | pages: write
16 | id-token: write
17 |
18 | # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
19 | # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
20 | concurrency:
21 | group: "pages"
22 | cancel-in-progress: false
23 |
24 | jobs:
25 |
26 | # Build job
27 | build:
28 | runs-on: ubuntu-latest
29 | steps:
30 | - name: Checkout
31 | uses: actions/checkout@v4
32 | - uses: actions/setup-node@v4
33 | with:
34 | node-version: ">=20.12.1"
35 | - run: npm install
36 | - name: Generate Editors draft
37 | shell: pwsh
38 | run: ./scripts/Generate.ps1
39 | - name: Setup Pages
40 | uses: actions/configure-pages@v5
41 | - name: Build with Jekyll
42 | uses: actions/jekyll-build-pages@v1
43 | with:
44 | source: ./doc
45 | destination: ./_site
46 | - name: Upload artifact
47 | uses: actions/upload-pages-artifact@v3
48 |
49 | # Deployment job
50 | deploy:
51 | environment:
52 | name: github-pages
53 | url: ${{ steps.deployment.outputs.page_url }}
54 | runs-on: ubuntu-latest
55 | needs: build
56 | steps:
57 | - name: Deploy to GitHub Pages
58 | id: deployment
59 | uses: actions/deploy-pages@v4
60 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright The Linux Foundation
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Welcome to the OpenAPI Moonwalk SIG!
2 |
3 | The OpenAPI Moonwalk [Special Interest Group](https://learn.openapis.org/glossary.html) (SIG) is working on the next major release of the OpenAPI Specification (OAS), version 4.0.
4 |
5 | ## Principles
6 |
7 | Moonwalk is being developed in accordance with the following principles, which you can read in more detail in [our 2025 blog post](https://www.openapis.org/blog/2025/02/05/moonwalk-2025-update) (an update to the [2024 post](https://www.openapis.org/blog/2023/12/06/openapi-moonwalk-2024)):
8 |
9 | 1. **Semantics**: Semantics provide purpose, whether the consumer is a human or an AI.
10 | 2. **Signatures**: An API operation is identifiable by its signature, which can be based on any aspect of HTTP mechanics.
11 | 3. **Inclusion**: Moonwalk aspires to describe all HTTP-based APIs while remaining neutral regarding any specific design debate.
12 | 4. **Foundational Interfaces**: Reduce the complexity for tooling authors by establishing standardized interfaces for parsing API description documents and defining consistent methods for expressing API structural semantics.
13 | 5. **Separation of Concerns**: Modularization will keep the scope of Moonwalk manageable with loose coupling among concerns such as HTTP interfaces ("API shapes"), deployment configuration, and content schema formats.
14 | 6. **Mechanical Upgrading**: An automated upgrade process from 3.x to 4.0 will be developed as part of the Moonwalk effort.
15 |
16 | ## Contributing
17 |
18 | As of March 2025, we are using the following documents and processes:
19 |
20 | * [The Initial Moonwalk Proposals](./doc/initial-proposals) launched this effort, and continue to serve as the reference point for our discussions
21 | * [Discussions](https://github.com/OAI/sig-moonwalk/discussions): All Moonwalk ideas should start as discussions
22 | * [Architectural Design Records (ADRs)](./doc/architecture) as discussions produce consensus, decisions are recorded as ADRs
23 | * [Issues](https://github.com/OAI/sig-moonwalk/issues) should ***only*** be used to track actionable work items
24 | * [Meeting Agendas](https://github.com/OAI/sig-moonwalk/discussions?discussions_q=is%3Aopen+label%3AHousekeeping) focus the discussion in our weekly calls, which are open to all
25 |
26 | ### Issues and formal documents
27 |
28 | We are not yet at the point of writing a formal specification, so there are very few reasons to file issues at this stage.
29 |
30 | We will begin writing a formal document once enough decisions have been made through ADRs that a coherent document can be structured.
31 |
32 | ### Writing ADRs
33 |
34 | Before writing an ADR to submit as a PR, please make sure that there is sufficient agreement to move ahead either in the discussion or by getting a decision in the weekly call.
35 |
36 | A good ADR decides _just enough_ of a topic to allow moving on to the next decision. As discussions tend to be rather sprawling, it might take several ADRs to resolve everything needed to close a discussion.
37 |
38 | Feedback on ADR PRs should be about whether the ADR captures the decision and all related concerns from the discussion. Details will likely be refined in the PR process, but if the direction of the decision is still being challenged, it is best to close the PR (or declare the ADR "rejected" before merging) and return to the GitHub discussion to re-build consensus.
39 |
--------------------------------------------------------------------------------
/doc/architecture/README.md:
--------------------------------------------------------------------------------
1 | # Moonwalk Architecture Documentation
2 |
3 | This directory documents the Moonwalk architecture, primarily by using Architectural Decision Records (ADRs).
4 |
5 | ADRs are stored in the [decisions](./decisions) directory, and should be created and managed using the [adr-tools](https://github.com/npryce/adr-tools) scripts which can be installed on any operating system. For those wishing to create ADRs manually, the [template](./decisions/template.md) is also provided.
6 |
7 | Supplemental material that is not part of a decision, such as examples or more detailed explorations of relevant topics, can be added in this directory rather than the decisions directory.
8 |
9 |
--------------------------------------------------------------------------------
/doc/architecture/decisions/0001-record-architecture-decisions.md:
--------------------------------------------------------------------------------
1 | # 1. Record architecture decisions
2 |
3 | Date: 2024-02-28
4 |
5 | ## Status
6 |
7 | Accepted
8 |
9 | ## Context
10 |
11 | We need to record the architectural decisions made on this project.
12 |
13 | ## Decision
14 |
15 | We will use Architecture Decision Records, as [described by Michael Nygard](http://thinkrelevance.com/blog/2011/11/15/documenting-architecture-decisions).
16 |
17 | ## Consequences
18 |
19 | See Michael Nygard's article, linked above. For a lightweight ADR toolset, see Nat Pryce's [adr-tools](https://github.com/npryce/adr-tools).
20 |
--------------------------------------------------------------------------------
/doc/architecture/decisions/0002-support-for-iris.md:
--------------------------------------------------------------------------------
1 | # 2. Support for IRIs
2 |
3 | Date: 2024-02-29
4 |
5 | ## Status
6 |
7 | Accepted
8 |
9 | ## Context
10 |
11 | The OpenAPI Specification (OAS) version 3 and earlier only support RFC 3986 URIs / URLs, for both API endpoints and for identifying and/or locating OpenAPI Description (OAD) documents. This means that users whose languages cannot be represented in the US-ASCII character set must encode all components (authorities, paths, query strings, and/or fragments) that include non-US-ASCII characters in accordance with [RFC 3987 §3.1](https://www.rfc-editor.org/rfc/rfc3987.html#section-3.1).
12 |
13 | The results of such encodings are not human-readible:
14 |
15 | IRI: https://www.例如.中国/api/中国/endpoint?例=如#如
16 | URI: https://www.xn--fsqu6v.xn--fiqs8s/api/%E4%B8%AD%E5%9B%BD/endpoint?%E4%BE%8B=%E5%A6%82#%E5%A6%82
17 |
18 | IRI: http://اب.تث.جح/خد/ذر/زس?شص=ضط;ظع=غف#قك
19 | URI: http://xn--mgbc.xn--pgbc.xn--rgbc/%D8%AE%D8%AF/%D8%B0%D8%B1/%D8%B2%D8%B3?%D8%B4%D8%B5=%D8%B6%D8%B7;%D8%B8%D8%B9=%D8%BA%D9%81#%D9%82%D9%83
20 |
21 | It's 2024, and the OAS is used all over the world. Everyone should be able to read identifiers in their own language and writing system.
22 |
23 | ## Decision
24 |
25 | All places where a URI/URL(-reference) would be used will be specified to allow an IRI(-reference) in UTF-8 encoding. If RFC 6570 URI Templates are used, then in accordance with [the last paragraph of section 1.1](https://www.rfc-editor.org/rfc/rfc6570.html#section-1.1) of that RFC, such templates will allow the use of the full IRI-supported character set.
26 |
27 | ## Consequences
28 |
29 | Implementations MUST support displaying IRIs and allowing their direct entry. When using an IRI as a URL, they will need to tranlsate the IRI to a URI first, or delegate such translation to an IRI-aware retrieval library. (Retrieval is not defined directly on IRI; there is no such thing as an "Internationalized Resource Locator").
30 |
31 | Implementations MAY perform operations such as relative reference resolution, normalization, comparison, etc. either on IRIs or on IRIs encoded to URIs, but MUST display the results of such operations as IRIs.
32 |
33 | Implementations that already support I18N should not have difficulty with the display requirements, although implementations that assume US-ASCII, or at least left-to-right character ordering, will be impacted more substantially.
34 |
--------------------------------------------------------------------------------
/doc/architecture/decisions/template.md:
--------------------------------------------------------------------------------
1 | # ADR template by Michael Nygard
2 |
3 | This is the template in [Documenting architecture decisions - Michael Nygard](http://thinkrelevance.com/blog/2011/11/15/documenting-architecture-decisions).
4 | You can use [adr-tools](https://github.com/npryce/adr-tools) for managing the ADR files.
5 |
6 | In each ADR file, write these sections:
7 |
8 | # Title
9 |
10 | ## Status
11 |
12 | What is the status, such as proposed, accepted, rejected, deprecated, superseded, etc.?
13 |
14 | ## Context
15 |
16 | What is the issue that we're seeing that is motivating this decision or change?
17 |
18 | ## Decision
19 |
20 | What is the change that we're proposing and/or doing?
21 |
22 | ## Consequences
23 |
24 | What becomes easier or more difficult to do because of this change?
25 |
--------------------------------------------------------------------------------
/doc/index.md:
--------------------------------------------------------------------------------
1 | # Moonwalk
2 |
3 | The OpenAPI Moonwalk [Special Interest Group](https://learn.openapis.org/glossary.html) (SIG) is working on the next major release of the OpenAPI Specification (OAS), version 4.0, with a goal of [publishing by the end of 2024](https://www.openapis.org/blog/2023/12/06/openapi-moonwalk-2024).
4 |
5 |
6 | [Editors Draft](moonwalk.html)
--------------------------------------------------------------------------------
/doc/initial-proposals/Deployments.md:
--------------------------------------------------------------------------------
1 | # Moonwalk Document refactoring
2 |
3 | The initial moonwalk proposal was primarily focused on how to describe the paths, requests, and responses of an API. Further discussions around the growing needs of the API community have identified additional opportunities for improvement by refactoring the structure of the OpenAPI document and the elements it contains. The first use case concerns improving lifecycle support as an API evolves.
4 |
5 | ## Requirements:
6 |
7 | - Decouple operations and schemas from the contexts (such as server or authentication) that are necessary to invoke those operations.
8 | - As an API changes over time, advertise a list of deployments that share a relationship to that API
9 | - Allow each deployment to independently refer to a different revisions of the description of that API as appropriate
10 | - Naturally support the existing use cases of OpenAPI, while also preserving the option to use other formats
11 |
12 | ## Current situation
13 |
14 | The description of an API contained in an OpenAPI document may actually be addressable at multiple locations (deployments), or it may not be implemented by any. In the case of industry standards bodies defining API shapes, the API may be implemented by completely different organizations than those describing the API shape.
15 |
16 | OpenAPI v3 does not make a clear delineation between the shape of the API and certain implementation details of the API by intention.
17 |
18 | ## Proposal
19 |
20 | For moonwalk this proposal suggests that we create a new object called `deployment` that captures the deployment details of a specific instance of an API along with certain implementation characteristics. The `deployment` object provides the context necessary to call API operations without providing any details about the shape of the API itself.
21 |
22 | ```mermaid
23 | classDiagram
24 | class OpenAPI {
25 |
26 | }
27 |
28 | OpenAPI "0" --> "0-1" Deployment:deployments
29 |
30 | class Deployment {
31 | title: string
32 | location: string
33 | clientRegistrationUrl: string
34 | apiDescriptionUrl: string
35 | }
36 |
37 |
38 | Deployment "0" --> "0..*" SecurityRequirement:security
39 |
40 |
41 | class SecurityRequirement {
42 |
43 | }
44 |
45 | OpenAPI "0" --> "*" pathItem:paths
46 | OpenAPI "0" --> "*" response:apiResponses
47 |
48 | class pathItem {
49 | uriTemplate: UriTemplate
50 | parameterSchema: JSONSchema
51 | }
52 | pathItem "0" --> "*" request:requests
53 | pathItem "0" --> "*" response:pathResponses
54 |
55 | class request {
56 | method: string
57 | contentType: string
58 | contentSchema: JSONSchema
59 | parameterSchema: JSONSchema
60 | }
61 | request "0" --> "*" response:responses
62 | request --> "0..*" Deployment:deployments
63 | class response {
64 | status: string
65 | contentType: string
66 | contentSchema: JSONSchema
67 | }
68 |
69 | ```
70 |
71 | In order to support a single-file expression, an OpenAPI document may contain zero or multiple Deployment objects that share the otherwise identical description contained within said OpenAPI document.
72 |
73 | ```yaml
74 | OpenApi: 4.0.0
75 | namespace: self
76 | deployments:
77 | default:
78 | title: "prod - ca"
79 | location: https://api.example.ca
80 | security:
81 | - basic: []
82 | clientRegistrationUrl: "https://developers.example.com/catalog/accounts" # optional, identifies where credentials may be obtained
83 | apiPaths: self // Do we really need this or can it be implicit?
84 | imports:
85 | - namespace: something
86 | href: https://example.org/somesharedstuff.json
87 | - namespace: someotherthing
88 | href: https://example.org/someothersharedstuff.json
89 | paths:
90 | /hello:
91 | requests:
92 | basic:
93 | deployments: ["default"]
94 | method: GET
95 | responses:
96 | success:
97 | status: '200'
98 | contentType: application/json
99 | contentSchema: someotherthing.HelloResponse
100 | fail:
101 | status: '5XX'
102 | contentType: application/json
103 | contentSchema: something.Error
104 |
105 | components:
106 | schemas:
107 | Error:
108 | type: object
109 | properties:
110 | code:
111 | type: integer
112 | format: int32
113 | message:
114 | type: string
115 | HelloResponse:
116 | type: object
117 | properties:
118 | message:
119 | type: string
120 | ```
121 |
122 | However, an OpenAPI document may also contain **only** Deployment entries, and each Deployment object can contain a pointer to a distinct API description document.
123 |
124 | ```yaml
125 | openapi: 4.0.0
126 | deployments:
127 | test:
128 | title: "test"
129 | location: https://test.api.example.com
130 | security:
131 | - basic: []
132 | clientRegistrationUrl: ""
133 | apiPaths: test
134 | canada:
135 | title: "prod - ca"
136 | location: https://api.example.ca
137 | security:
138 | - basic: []
139 | clientRegistrationUrl: "https://developers.example.com/catalog/accounts"
140 | apiPaths: canada
141 | usa:
142 | title: "prod - us"
143 | location: https://api.example.us
144 | security:
145 | - basic: []
146 | clientRegistrationUrl: "https://developers.example.com/catalog/accounts"
147 | apiPaths: usa
148 | imports:
149 | - namespace: test
150 | href: https://github.com/example-co/apis/blob/9182274701c279aedc4107fedf630639d7d70bbb/accounts/openapi.2.0.4.yaml
151 | - namespace: canada
152 | href: https://developers.example.com/catalog/accounts/openapi.2.0.2.yaml
153 | - namespace: usa
154 | href: https://developers.example.com/catalog/accounts/openapi.2.0.2.yaml
155 |
156 | ```
157 |
--------------------------------------------------------------------------------
/doc/initial-proposals/README.md:
--------------------------------------------------------------------------------
1 | # OpenAPI v4 (aka Moonwalk) Proposal
2 |
3 | > note: Warning, disclaimer, caveat. This is very early thinking and is subject to major change and potential abandonment. However, intial reactions to the direction have been positive and so ready for input from a wider group of people.
4 |
5 | ## Introduction
6 | This refresh of OpenAPI attempts to walk a fine line of being simpler while at the same time being more flexible. It attempts to lean more on existing standards and to minimize adding new functionality. The essence of the restructured model is captured in this diagram.
7 |
8 |
9 | ```mermaid
10 | classDiagram
11 | class OpenApi {
12 |
13 | }
14 | OpenApi "0" --> "*" pathItem:paths
15 | OpenApi "0" --> "*" response:apiResponses
16 |
17 | class pathItem {
18 | uriTemplate: UriTemplate
19 | parameterSchema: JSONSchema
20 | }
21 | pathItem "0" --> "*" request:requests
22 | pathItem "0" --> "*" response:pathResponses
23 |
24 | class request {
25 | method: string
26 | contentType: string
27 | contentSchema: JSONSchema
28 | parameterSchema: JSONSchema
29 | }
30 | request "0" --> "*" response:responses
31 |
32 | class response {
33 | status: string
34 | contentType: string
35 | contentSchema: JSONSchema
36 | }
37 |
38 |
39 | ```
40 |
41 | ## Goals
42 | The primary goal of this proposal for a major new version of OpenAPI is to make it more approachable in order. One way it does so is by eliminating complexity that exists in OpenAPI v3. In addition, it aims to:
43 |
44 | - Support APIs that have different responses based on query parameters, headers and request bodies.
45 | - Support a broader range of URL design patterns
46 | - Reduce nested structures to improve readability and editability
47 | - Improve reusability of request and response patterns
48 |
49 | OpenAPI has become the defacto standard for API descriptions, and it benefits from a very wide range of tooling support. However, due to its historic opinions of how an HTTP API should be designed, there are some scenarios that v3 cannot support. On the one hand, some in the community are asking for increased descriptiveness to support more scenarios. Yet at the same time, other bemoan how OpenAPI has become too complex for hand authoring.
50 |
51 | This major update to the OpenAPI specification attempts to simplify the design by focusing on three main structural components: `pathItem`, `request`, and `response`. In OpenAPI v3, a `pathItem` had a set of operations, one for each HTTP method it supported. There was an implicit assumption in this design that a HTTP method on a path could only describe single interaction, with same set of responses. Moonwalk, by contrast, has minimal constraints on how many different types of requests could be performed on a single path. Almost, any part of the request can be used to signal that there may be a unique set of responses.
52 |
53 | In OpenAPI v3, the key for a `PathItem` object was limited to just the path portion of a URL. Moonwalk proposes that `pathItem` keys can be complete [URI Templates][uri-templates-rfc]. This allows query parameters to be used in the identification of a resource and its corresponding requests, and it removes the need for parameter definitions to contain serialization information as the URI Template can fully describe how URI template parameters should be serialized. This use of an internet standard will reduce the work required by tooling to support URL construction. This may address the long standing issue of unambiguously correlating URLs with the appropriate `pathItem`.
54 |
55 | [uri-templates-rfc]: https://www.rfc-editor.org/rfc/rfc6570
56 |
57 | ## Requests
58 |
59 | `request` objects flatten `operation` objects, `requestBody` objects, and `mediaType` objects into a single object. Deep nesting can become unnecessarily cumbersome for reading and writing OpenAPI descriptions. A `pathItem` object can have multiple request objects. Each request object is named and must have a method specified. It may have a `contentType`, `contentSchema`, and `parameterSchema` defined. This new model allows different responses to be described for different request body media types. However, it does make it more cumbersome for accepting two equivalent media types like `text/json` and `application/json`.
60 |
61 | By naming the `request` objects we can give the reader a friendly name to understand the purpose of the `request`. This is especially helpful when there are potentially multiple `request` objects that use the same method.
62 |
63 | Some tooling will need to be able to correlate an actual HTTP request with the corresponding OpenAPI description. This request selection process starts with matching on HTTP method and if present the request's `Content-Type`. If further selection is required, the `parameterSchema` JSON Schema of each `request` object can be used to match with a JSON representation of the HTTP request parameters, headers and request body.
64 |
65 | ## Responses
66 | Responses also have a friendly name. `response` objects remove the need for the nesting of media-type objects by allowing multiple responses with the same status code but with different content types. `response` objects can be defined at the request level, the path, or globally. This reduces duplicatation of responses that are consistent across the API or for all requests associated to path.
67 |
68 | A side effect of giving names to requests and responses is that it makes the predictions from AIs like GitHub Copilot significantly more effective. It also makes folded content more readable in editors in both YAML and JSON because there is a readable name with the details hidden.
69 |
70 | ## Simple Example
71 |
72 | ```yaml
73 | openapi: 4.0.0
74 | info:
75 | title: Simplest thing that works
76 | version: 0.5.0
77 | paths:
78 | "speakers":
79 | requests:
80 | createSpeaker:
81 | method: post
82 | contentType: application/json
83 | contentSchema:
84 | $ref: "#/components/schemas/speaker"
85 | responses:
86 | created:
87 | status: 201
88 | getSpeakers:
89 | method: get
90 | responses:
91 | ok:
92 | status: 200
93 | contentType: application/json
94 | contentSchema:
95 | type: array
96 | items:
97 | $ref: "#/components/schemas/speaker"
98 | pathResponses:
99 | notFound:
100 | status: 404
101 | contentType: application/http-problem
102 | apiResponses:
103 | serverError:
104 | status: 5XX
105 | contentType: application/http-problem
106 | components:
107 | schemas:
108 | Speaker:
109 | type: object
110 | properties:
111 | name:
112 | type: string
113 | ```
114 | As compared to 3.1.0
115 |
116 | ```yaml
117 | openapi: 3.1.0
118 | info:
119 | title: Simplest thing that works
120 | version: 0.5.0
121 | paths:
122 | "/speakers":
123 | post:
124 | requestBody:
125 | content:
126 | application/json:
127 | schema:
128 | $ref: "#/components/schemas/speaker"
129 | responses:
130 | 201:
131 | description: created
132 | 404:
133 | description: notFound
134 | content:
135 | application/http-problem: {}
136 | 5XX:
137 | description: serverError
138 | content:
139 | application/http-problem: {}
140 |
141 | get:
142 | responses:
143 | 200:
144 | description: retrieved
145 | content:
146 | application/json:
147 | schema:
148 | type: array
149 | items:
150 | $ref: "#/components/schemas/speaker"
151 | 404:
152 | description: notFound
153 | content:
154 | application/http-problem: {}
155 | 5XX:
156 | description: serverError
157 | content:
158 | application/http-problem: {}
159 | components:
160 | schemas:
161 | Speaker:
162 | type: object
163 | properties:
164 | name:
165 | type: string
166 | ```
167 | In this simple example, the moonwalk version has 20% less lines and one less level of indentation.
168 |
169 | ## JSONSchema for Parameters
170 | By using a JSON Schema object to describe input parameters we can futher disambiguate between the different kinds of requests supported by a path. This enables supporting a whole class of feature requests where API designers want to differentiate operations by [query parameter](examples/parameterSchema.yaml), [header](examples/rpc.yaml) or even [request body](examples/rpc.yaml) content. We can use `allOf` rules to combine parameters defined at the path level and at the request level. We can also have [interdependency rules](examples/dependentParameters.yaml) between parameters. For runtime validation of requests, once filtered by method and contentType, further disambiguation can be done by creating a `oneOf` of the `parameterSchema` for each ambiguous request that is `allOf`'d with the `pathItem`'s `parameterSchema`.
171 |
172 | ## UriTemplates
173 | By using full URI Templates to define the `pathItem` we can now use query parameters to distinguish between resources and the serialization rules of parameters no longer need to be encoded in the parameter object. OpenAPI v3 enhanced parameter objects to use the serialization features of a `uriTemplate` but without using the syntax. With this change, we can get full access to the `uriTemplate` features and use the standard syntax.
174 |
175 | Using full `uriTemplate` syntax allows us to support optional path parameters and multi-segment path parameters. We still need to address the issue of URL to `uriTemplate` mapping where there is ambiguity.
176 |
177 | ## Components
178 | `request`, `response`, and `schema` objects may be declared as reusable components. This allows `parameterSchema` to either reuse entire schemas of parameter descriptions or use `allOf` to reuse sets of parameters. As the OpenAPI reference object is now independent to the JSON Schema `$ref`, we are free to support OpenAPI Reference arrays as well as reference objects. This will allow reusing a set of requests or a set of responses.
179 |
180 | ## Examples
181 |
182 | - [PetStore Example](examples/petstore.yaml)
183 | - [Parameter Schemas](examples/parameterSchema.yaml)
184 | - [Aggregated API](examples/aggregatedapi.yaml)
185 | - [Dependent Parameters](examples/dependentParameters.yaml)
186 | - [rpc](examples/rpc.yaml)
187 |
--------------------------------------------------------------------------------
/doc/initial-proposals/changes.md:
--------------------------------------------------------------------------------
1 | # Major Changes from V3
2 | * PathItem object is identified using a full UriTemplate
3 | * Operation objects are replaced by requests objects and are named
4 | * Response objects are named.
5 | * Info object is optional to allow aggregation of files into a single API
6 | * Parameters are defined by a JSON Schema object that is a combination of the pathItem parameterSchema and the request parameterSchema
7 | * pathitem key is relative and does NOT start with a slash
8 |
9 |
10 | # Issues addressed by this change
11 | ## no more parameter arrays
12 | ## no more deeply nested structure
13 | ## Collapsed structure shows names of requests and responses.
14 | ## Responses are named and use pattern matching so are much more flexible.
15 | ## ParameterSchema can be used to define interdependent parameters
16 | ## Treating parameters as JSON Schema objects allows doing allOf to reuse parameter groups
17 | ## Creating names for requests and responses provides a hint for co-pilot to suggest the right response/request
--------------------------------------------------------------------------------
/doc/initial-proposals/examples/FlatOperations/OperationList.yaml:
--------------------------------------------------------------------------------
1 | openapi: 4.0.0
2 | operations:
3 | - id: GetFlat
4 | name: Get
5 | method: GET
6 | uriTemplate: /api/v1/flat
7 | description: Get a list of flat objects
8 | responses:
9 | - status: 200
10 | description: OK
11 | contentType: application/json
12 | schema:
13 | type: array
14 | items:
15 | $ref: '#/components/schemas/Flat'
--------------------------------------------------------------------------------
/doc/initial-proposals/examples/aggregatedapi.yaml:
--------------------------------------------------------------------------------
1 | openapi: 4.0.0
2 | info:
3 | title: Aggregation API
4 | version: 1.0.0
5 | paths:
6 | $ref: ## $ref can be an array
7 | - "./accounting.yaml#/paths"
8 | - "./inventory.yaml#/paths"
9 | - "./purchasing.yaml#/paths"
--------------------------------------------------------------------------------
/doc/initial-proposals/examples/dependentParameters.yaml:
--------------------------------------------------------------------------------
1 | openapi: 4.0.0
2 | info:
3 | title: Parameters with interdependencies
4 | description: Examples of parameters with interdependencies come from ASC 2022 talk by Alberto Martin Lopez
5 | version: 0.5.0
6 | paths:
7 | # ---------
8 | # Requires - The presence of a parameter (or a specific parameter value)
9 | # requires the presence of another parameter
10 | # ---------
11 |
12 | # Bing Web Search
13 | # if promote is specified then answerCount must also be specified
14 | "requires{?promote,answerCount}":
15 | requests:
16 | constrainedRequest:
17 | parameterSchema:
18 | type: object
19 | properties:
20 | from:
21 | type: string
22 | messagingServiceId:
23 | type: string
24 | oneOf:
25 | - not:
26 | - required: [promote]
27 | - required: [answerCount]
28 | responses:
29 | ok:
30 | status: 200
31 |
32 | # Tropo
33 | # if type == 'number' then prefix or number must be specified
34 | "requires{?type,prefix,number}":
35 | requests:
36 | constrainedRequest:
37 | parameterSchema:
38 | type: object
39 | properties:
40 | type:
41 | type: string
42 | prefix:
43 | type: string
44 | number:
45 | type: string
46 | oneOf:
47 | - not:
48 | - properties:
49 | type:
50 | enum: ['number']
51 | - required: [prefix]
52 | - required: [number]
53 | responses:
54 | ok:
55 | status: 200
56 |
57 | # ---------
58 | # Or - Given a set of parameters, one or more of them must be included.
59 | # ---------
60 |
61 | # Flickr
62 | # Either title or description must be specified
63 | "or{?title,description}":
64 | requests:
65 | constrainedRequest:
66 | parameterSchema:
67 | type: object
68 | properties:
69 | title:
70 | type: string
71 | description:
72 | type: string
73 | anyOf:
74 | - required: [title]
75 | - required: [description]
76 | responses:
77 | ok:
78 | status: 200
79 |
80 | # NationBuilder
81 | # donor_id, email, or first_name and last_name must be specified
82 | "or{?donor_id,email,first_name,last_name}":
83 | requests:
84 | constrainedRequest:
85 | parameterSchema:
86 | type: object
87 | properties:
88 | donor_id:
89 | type: string
90 | email:
91 | type: string
92 | first_name:
93 | type: string
94 | last_name:
95 | type: string
96 | anyOf:
97 | - required: [donor_id]
98 | - required: [email]
99 | - required: [first_name,last_name]
100 | responses:
101 | ok:
102 | status: 200
103 |
104 | # ---------
105 | # OnlyOne - Given a set of parameters, one and only one of them must be included.
106 | # ---------
107 |
108 | # Twilio SMS
109 | # Either from or messagingServiceId must be specified but not both
110 | "onlyOne{?from,messagingServiceId}":
111 | parameterSchema:
112 | type: object
113 | properties:
114 | from:
115 | type: string
116 | messagingServiceId:
117 | type: string
118 | requests:
119 | constrainedRequest:
120 | parameterSchema:
121 | oneOf:
122 | - required: [from]
123 | - required: [messagingServiceId]
124 | responses:
125 | ok:
126 | status: 200
127 |
128 | # Yelp
129 | # Either location or (latitude and longitude) must be specified but not both
130 | "onlyOne{?location,latitude,longitude}":
131 | parameterSchema:
132 | type: object
133 | properties:
134 | location:
135 | type: string
136 | latitude:
137 | type: string
138 | longitude:
139 | type: string
140 | requests:
141 | constrainedRequest:
142 | parameterSchema:
143 | oneOf:
144 | - required: [location]
145 | not:
146 | anyOf:
147 | - required: [latitude]
148 | - required: [longitude]
149 | - required: [latitude,longitude]
150 | responses:
151 | ok:
152 | status: 200
153 |
154 | # ---------
155 | # AllOrNone - Given a set of parameters, either all of them are provided or none of them is.
156 | # ---------
157 |
158 | # GitHub
159 | # subject_type and subject_id are both specified or neither is specified
160 | "allOrNone{?subject_type,subject_id}":
161 | requests:
162 | constrainedRequest:
163 | parameterSchema:
164 | type: object
165 | properties:
166 | subject_type:
167 | type: string
168 | subject_id:
169 | type: string
170 | oneOf:
171 | - required: [subject_type,subject_id]
172 | - not:
173 | anyOf:
174 | - required: [subject_type]
175 | - required: [subject_id]
176 | responses:
177 | ok:
178 | status: 200
179 |
180 | # Stripe
181 | # value is present if and only if type is 'bucket'
182 | "allOrNone{?value,type}":
183 | requests:
184 | constrainedRequest:
185 | parameterSchema:
186 | type: object
187 | properties:
188 | value:
189 | type: string
190 | type:
191 | type: string
192 | oneOf:
193 | - properties:
194 | type:
195 | enum: ['bucket']
196 | required: [type,value]
197 | - not:
198 | properties:
199 | type:
200 | enum: ['bucket']
201 | required: [type,value]
202 | responses:
203 | ok:
204 | status: 200
205 |
206 | # ---------
207 | # ZeroOrOne - Given a set of parameters, at most one of can be included.
208 | # ---------
209 |
210 | # YouTube
211 | # specify zero or one of forContentOwner, forDeveloper, forMine, or relatedToVideoId
212 | "zeroOrOne{?forContentOwner,forDeveloper,forMine,relatedToVideoId}":
213 | requests:
214 | constrainedRequest:
215 | parameterSchema:
216 | type: object
217 | properties:
218 | forContentOwner:
219 | type: string
220 | forDeveloper:
221 | type: string
222 | forMine:
223 | type: string
224 | relatedToVideoId:
225 | type: string
226 | oneOf:
227 | - required: [forContentOwner]
228 | not:
229 | anyOf:
230 | - required: [forDeveloper]
231 | - required: [forMine]
232 | - required: [relatedToVideoId]
233 | - required: [forDeveloper]
234 | not:
235 | anyOf:
236 | - required: [forContentOwner]
237 | - required: [forMine]
238 | - required: [relatedToVideoId]
239 | - required: [forMine]
240 | not:
241 | anyOf:
242 | - required: [forContentOwner]
243 | - required: [forDeveloper]
244 | - required: [relatedToVideoId]
245 | - required: [relatedToVideoId]
246 | not:
247 | anyOf:
248 | - required: [forContentOwner]
249 | - required: [forDeveloper]
250 | - required: [forMine]
251 | - not:
252 | anyOf:
253 | - required: [forContentOwner]
254 | - required: [forDeveloper]
255 | - required: [forMine]
256 | - required: [relatedToVideoId]
257 | responses:
258 | ok:
259 | status: 200
260 |
261 | # Google Maps
262 | # radius must not be included if rankby == 'distance'
263 | "zeroOrOne{?rankby,radius}":
264 | requests:
265 | constrainedRequest:
266 | parameterSchema:
267 | type: object
268 | properties:
269 | radius:
270 | type: string
271 | rankby:
272 | type: string
273 | anyOf:
274 | - not:
275 | required: [radius]
276 | - not:
277 | properties:
278 | rankby:
279 | enum: ['distance']
280 | responses:
281 | ok:
282 | status: 200
283 |
284 | # ---------
285 | # Complex - Involves two or more of the previous dependencies.
286 | # ---------
287 |
288 | # Stripe
289 | # If subscription_trial_end is specified, one of subscription_items or subscription is required
290 | "complex{?subscription_trial_end,subscription_items,subscription}":
291 | requests:
292 | constrainedRequest:
293 | parameterSchema:
294 | type: object
295 | properties:
296 | subscription_trial_end:
297 | type: string
298 | subscription_items:
299 | type: string
300 | subscription:
301 | type: string
302 | oneOf:
303 | - not:
304 | required: [subscription_trial_end]
305 | - oneOf:
306 | - required: [subscription_items]
307 | - required: [subscription]
308 | responses:
309 | ok:
310 | status: 200
311 |
312 | # Foursquare
313 | # radius is only valid for requests with intent=browse or requests with intent=checkin and categoryId or query
314 | "complex{?radius,intent,categoryId,query}":
315 | requests:
316 | constrainedRequest:
317 | parameterSchema:
318 | type: object
319 | properties:
320 | radius:
321 | type: number
322 | intent:
323 | type: string
324 | categoryId:
325 | type: string
326 | query:
327 | type: string
328 | anyOf:
329 | - not:
330 | required: [radius]
331 | - properties:
332 | intent:
333 | enum: ['browse']
334 | required: ['intent']
335 | - properties:
336 | intent:
337 | enum: ['checkin']
338 | required: [intent]
339 | anyOf:
340 | - required: [categoryId]
341 | - required: [query]
342 | responses:
343 | ok:
344 | status: 200
345 |
--------------------------------------------------------------------------------
/doc/initial-proposals/examples/parameterSchema.yaml:
--------------------------------------------------------------------------------
1 | openapi: 4.0.0
2 | info:
3 | title: Parameters defined at the path and at the request level
4 | version: 0.5.0
5 | paths:
6 | 'speakers/{speakerId}{?format}': ## as format is optional, it does not need to be declared for each request, only the ones that use it
7 | parameterSchema:
8 | type: object
9 | properties:
10 | speakerId:
11 | type: string
12 | title: Speaker ID
13 | requests:
14 | getSpeakerAsJson: ## the requests getSpeakerAsJson and getSpeakerAsCSV could be declared as a single request but with two 200 responses.
15 | parameterSchema:
16 | type: object
17 | properties:
18 | format:
19 | type: string
20 | const: json ## This example shows how you use query parameters to distinction between requests.
21 | method: get
22 | responses:
23 | ok:
24 | status: 200
25 | contentType: application/json
26 | contentSchema:
27 | $ref: '#/components/schemas/speaker'
28 | getSpeakerAsCSV:
29 | parameterSchema:
30 | type: object
31 | properties:
32 | format:
33 | type: string
34 | const: csv
35 | method: get
36 | responses:
37 | ok:
38 | status: 200
39 | contentType: text/csv
40 | contentSchema:
41 | type: string
42 | updateSpeaker:
43 | method: put
44 | contentType: application/json
45 | contentSchema:
46 | $ref: '#/components/schemas/speaker'
47 | responses:
48 | ok:
49 | status: 200
50 | contentType: application/json
51 | contentSchema:
52 | $ref: '#/components/schemas/speaker'
53 | deleteSpeaker:
54 | method: delete
55 | responses:
56 | ok:
57 | status: 200
58 | responses:
59 | notFound:
60 | status: 404
61 | contentType: application/http-problem
62 | responses:
63 | serverError:
64 | status: 5XX
65 | contentType: application/http-problem
66 | components:
67 | schemas:
68 | Speaker:
69 | type: object
70 | properties:
71 | name:
72 | type: string
73 |
--------------------------------------------------------------------------------
/doc/initial-proposals/examples/petstore.yaml:
--------------------------------------------------------------------------------
1 | openapi: 4.0.0
2 | info:
3 | title: Swagger Petstore - OpenAPI 4.0
4 | description: |-
5 | This is a sample Pet Store Server based on the OpenAPI 3.0 specification. You can find out more about
6 | Swagger at [http://swagger.io](http://swagger.io). In the third iteration of the pet store, we've switched to the design first approach!
7 | You can now help us improve the API whether it's by making changes to the definition itself or to the code.
8 | That way, with time, we can improve the API in general, and expose some of the new features in OAS3.
9 |
10 | Some useful links:
11 | - [The Pet Store repository](https://github.com/swagger-api/swagger-petstore)
12 | - [The source API definition for the Pet Store](https://github.com/swagger-api/swagger-petstore/blob/master/src/main/resources/openapi.yaml)
13 | termsOfService: http://swagger.io/terms/
14 | contact:
15 | email: apiteam@swagger.io
16 | license:
17 | name: Apache 2.0
18 | url: http://www.apache.org/licenses/LICENSE-2.0.html
19 | version: 1.0.15
20 | paths:
21 | "pet": ## Path is a relative reference. It needs to be anchored to a base by a servers URL. Or if you put an absolute URL in the path, it will be used as is.
22 | requests:
23 | CreatePet: ## Operation name is elevated to be a key for requests but is only unique within the pathItem
24 | method: POST
25 | contentType: application/json
26 | contentSchema:
27 | $ref: "#/components/schemas/Pet"
28 | responses:
29 | Created: ## response names can use conventions to map to request names
30 | status: 201
31 | contentType: application/json
32 | FailPetCreate:
33 | status: 400
34 | contentType: application/http-problem
35 | RetrievePets:
36 | method: GET
37 | responses:
38 | Ok:
39 | status: 200
40 | contentType: application/json
41 | contentSchema:
42 | type: array
43 | items:
44 | $ref: "#/components/schemas/Pet"
45 | OkinCSV:
46 | status: 200
47 | contentType: text/csv
48 | contentSchema:
49 | type: string
50 | FailPetRetrieve:
51 | status: 400
52 | contentType: application/http-problem
53 | "pet/findByStatus?status={status}":
54 | requests:
55 | findPetsByStatus:
56 | description: Multiple status values can be provided with comma separated strings
57 | method: GET
58 | parameterSchema:
59 | type: object
60 | required:
61 | - status
62 | properties:
63 | status:
64 | type: string
65 | enum: [available, pending, sold]
66 | responses:
67 | Ok:
68 | status: 200
69 | contentType: application/json
70 | contentSchema:
71 | type: array
72 | items:
73 | $ref: "#/components/schemas/Pet"
74 | failBadStatus:
75 | status: 400
76 | description: Invalid status value
77 | "pet/findByTags?tags={tags}":
78 | requests:
79 | findPetsByTags:
80 | description: Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.
81 | method: GET
82 | parameterSchema:
83 | type: object
84 | required:
85 | - tags
86 | properties:
87 | tags:
88 | type: string
89 | responses:
90 | Ok:
91 | status: 200
92 | contentType: application/json
93 | contentSchema:
94 | type: array
95 | items:
96 | $ref: "#/components/schemas/Pet"
97 | FailBadTag:
98 | status: 400
99 | description: Invalid tag value
100 | "pet/{petId}": ## Paths support full UriTemplate syntax to enable disambiguation of operations by query parameters. This means we don't need all the style/explode hints in the parameter object.
101 | parameterSchema:
102 | type: object
103 | properties:
104 | petId:
105 | type: string
106 | format: int64
107 | requests:
108 | RetrievePet:
109 | method: GET
110 | responses:
111 | retrieved:
112 | status: 200
113 | description: "The pet was retrieved" ## description is optional
114 | contentType: application/json
115 | contentSchema:
116 | $ref: "#/components/schemas/Pet"
117 | UpdatePet:
118 | method: PUT
119 | contentType: application/json
120 | contentSchema:
121 | $ref: "#/components/schemas/Pet"
122 | responses:
123 | Updated:
124 | status: 200
125 | description: "The pet was updated"
126 | contentType: application/json
127 | contentSchema:
128 | $ref: "#/components/schemas/Pet"
129 | FailPetUpdate:
130 | status: 400
131 | description: "The pet was not updated"
132 | UpdatePetWithForm:
133 | method: POST
134 | contentType: application/x-www-form-urlencoded
135 | contentSchema:
136 | type: object
137 | properties:
138 | name:
139 | type: string
140 | status:
141 | type: string
142 | responses:
143 | Updated:
144 | status: 200
145 | description: "The pet was updated"
146 | contentType: application/json
147 | contentSchema:
148 | $ref: "#/components/schemas/Pet"
149 | FailPetUpdate:
150 | status: 400
151 | description: "The pet was not updated"
152 | DeletePet:
153 | method: DELETE
154 | responses:
155 | deleted:
156 | status: 204
157 | description: "The pet was deleted"
158 | responses:
159 | petNotFound:
160 | status: 404
161 | description: "The pet was not found"
162 | serverError:
163 | status: 5XX
164 | "pet/{petId}/uploadImage{?additionalMetadata}":
165 | parameterSchema:
166 | properties:
167 | petId:
168 | type: string
169 | format: uuid
170 | additionalMetadata:
171 | type: string
172 | requests:
173 | uploadFile:
174 | summary: "Uploads an image"
175 | method: POST
176 | contentType: application/octet-stream
177 | responses:
178 | ok:
179 | status: 200
180 | contentType: application/json
181 | contentSchema:
182 | $ref: "#/components/schemas/ApiResponse"
183 | fail:
184 | status: 400
185 | "/store/order":
186 | requests:
187 | CreateOrder:
188 | method: POST
189 | contentType: application/json
190 | contentSchema:
191 | $ref: "#/components/schemas/Order"
192 | responses:
193 | Created:
194 | status: 201
195 | contentType: application/json
196 | contentSchema:
197 | $ref: "#/components/schemas/Order"
198 | FailOrderCreate:
199 | status: 400
200 | RetrieveOrders:
201 | method: GET
202 | responses:
203 | Ok:
204 | status: 200
205 | contentType: application/json
206 | contentSchema:
207 | type: array
208 | items:
209 | $ref: "#/components/schemas/Order"
210 | FailOrderRetrieve:
211 | status: 400
212 | "/store/order/{orderId}":
213 | parameterSchema:
214 | properties:
215 | orderId:
216 | type: string
217 | format: int64
218 | requests:
219 | RetrieveOrder:
220 | method: GET
221 | responses:
222 | Ok:
223 | status: 200
224 | contentType: application/json
225 | contentSchema:
226 | $ref: "#/components/schemas/Order"
227 | FailOrderRetrieve:
228 | status: 400
229 | DeleteOrder:
230 | method: DELETE
231 | responses:
232 | deleted:
233 | status: 204
234 | description: "The order was deleted"
235 | responses:
236 | orderNotFound:
237 | status: 404
238 | description: "The order was not found"
239 | serverError:
240 | status: 5XX
241 | components:
242 | schemas:
243 | Order:
244 | type: object
245 | properties:
246 | id:
247 | type: integer
248 | format: int64
249 | example: 10
250 | petId:
251 | type: integer
252 | format: int64
253 | example: 198772
254 | quantity:
255 | type: integer
256 | format: int32
257 | example: 7
258 | shipDate:
259 | type: string
260 | format: date-time
261 | status:
262 | type: string
263 | description: Order Status
264 | example: approved
265 | enum:
266 | - placed
267 | - approved
268 | - delivered
269 | complete:
270 | type: boolean
271 | xml:
272 | name: order
273 | Customer:
274 | type: object
275 | properties:
276 | id:
277 | type: integer
278 | format: int64
279 | example: 100000
280 | username:
281 | type: string
282 | example: fehguy
283 | address:
284 | type: array
285 | xml:
286 | name: addresses
287 | wrapped: true
288 | items:
289 | $ref: "#/components/schemas/Address"
290 | xml:
291 | name: customer
292 | Address:
293 | type: object
294 | properties:
295 | street:
296 | type: string
297 | example: 437 Lytton
298 | city:
299 | type: string
300 | example: Palo Alto
301 | state:
302 | type: string
303 | example: CA
304 | zip:
305 | type: string
306 | example: "94301"
307 | xml:
308 | name: address
309 | Category:
310 | type: object
311 | properties:
312 | id:
313 | type: integer
314 | format: int64
315 | example: 1
316 | name:
317 | type: string
318 | example: Dogs
319 | xml:
320 | name: category
321 | User:
322 | type: object
323 | properties:
324 | id:
325 | type: integer
326 | format: int64
327 | example: 10
328 | username:
329 | type: string
330 | example: theUser
331 | firstName:
332 | type: string
333 | example: John
334 | lastName:
335 | type: string
336 | example: James
337 | email:
338 | type: string
339 | example: john@email.com
340 | password:
341 | type: string
342 | example: "12345"
343 | phone:
344 | type: string
345 | example: "12345"
346 | userStatus:
347 | type: integer
348 | description: User Status
349 | format: int32
350 | example: 1
351 | xml:
352 | name: user
353 | Tag:
354 | type: object
355 | properties:
356 | id:
357 | type: integer
358 | format: int64
359 | name:
360 | type: string
361 | xml:
362 | name: tag
363 | Pet:
364 | required:
365 | - name
366 | - photoUrls
367 | type: object
368 | properties:
369 | id:
370 | type: integer
371 | format: int64
372 | example: 10
373 | name:
374 | type: string
375 | example: doggie
376 | category:
377 | $ref: "#/components/schemas/Category"
378 | photoUrls:
379 | type: array
380 | xml:
381 | wrapped: true
382 | items:
383 | type: string
384 | xml:
385 | name: photoUrl
386 | tags:
387 | type: array
388 | xml:
389 | wrapped: true
390 | items:
391 | $ref: "#/components/schemas/Tag"
392 | status:
393 | type: string
394 | description: pet status in the store
395 | enum:
396 | - available
397 | - pending
398 | - sold
399 | xml:
400 | name: pet
401 | ApiResponse:
402 | type: object
403 | properties:
404 | code:
405 | type: integer
406 | format: int32
407 | type:
408 | type: string
409 | message:
410 | type: string
411 | xml:
412 | name: "##default"
413 | requestBodies:
414 | Pet:
415 | description: Pet object that needs to be added to the store
416 | content:
417 | application/json:
418 | schema:
419 | $ref: "#/components/schemas/Pet"
420 | application/xml:
421 | schema:
422 | $ref: "#/components/schemas/Pet"
423 | UserArray:
424 | description: List of user object
425 | content:
426 | application/json:
427 | schema:
428 | type: array
429 | items:
430 | $ref: "#/components/schemas/User"
431 | securitySchemes:
432 | petstore_auth:
433 | type: oauth2
434 | flows:
435 | implicit:
436 | authorizationUrl: https://petstore3.swagger.io/oauth/authorize
437 | scopes:
438 | write:pets: modify pets in your account
439 | read:pets: read your pets
440 | api_key:
441 | type: apiKey
442 | name: api_key
443 | in: header
444 |
--------------------------------------------------------------------------------
/doc/initial-proposals/examples/rpc.yaml:
--------------------------------------------------------------------------------
1 | openapi: 4.0.0
2 | info:
3 | title: RPC API
4 | version: 1.0.0
5 | paths:
6 | "/service":
7 | requests:
8 | createFoo:
9 | method: post
10 | parameterSchema:
11 | type: object
12 | properties:
13 | header: ## We can either use this specially named property or create a first class headerSchema property on the Request Object
14 | type: object
15 | properties:
16 | path:
17 | const: service.createFoo ## path Header field used to convey the RPC method
18 | contentType: application/json
19 | contentSchema:
20 | $ref: "#/components/schemas/foo"
21 | responses:
22 | ok:
23 | status: 201
24 | contentType: application/json
25 | contentSchema:
26 | $ref: "#/components/schemas/foo"
27 | updateFoo:
28 | method: post
29 | parameterSchema:
30 | type: object
31 | properties:
32 | header:
33 | type: object
34 | properties:
35 | path:
36 | const: service.updateFoo ## path Header field used to convey the RPC method
37 | contentType: application/json
38 | contentSchema:
39 | $ref: "#/components/schemas/foo"
40 | responses:
41 | ok:
42 | status: 200
43 | contentType: application/json
44 | contentSchema:
45 | $ref: "#/components/schemas/foo"
46 | getFoo:
47 | method: get
48 | parameterSchema:
49 | type: object
50 | properties:
51 | header:
52 | type: object
53 | properties:
54 | path:
55 | const: service.getFoo ## path Header field used to convey the RPC method
56 | responses:
57 | ok:
58 | status: 200
59 | contentType: application/json
60 | contentSchema:
61 | $ref: "#/components/schemas/foo"
62 | deleteFoo:
63 | method: post
64 | parameterSchema:
65 | type: object
66 | properties:
67 | header:
68 | type: object
69 | properties:
70 | path:
71 | const: service.deleteFoo
72 | responses:
73 | ok:
74 | status: 200
75 | contentType: application/json
76 | contentSchema:
77 | $ref: "#/components/schemas/foo"
78 | "/jsonrpc":
79 | requests:
80 | getFoo:
81 | method: post
82 | parameterSchema:
83 | type: object
84 | properties:
85 | body:
86 | type: object
87 | properties:
88 | jsonrpc:
89 | const: 2.0
90 | method:
91 | const: getFoo
92 | params:
93 | type: object
94 | properties:
95 | id:
96 | type: string
97 | responses:
98 | ok:
99 | status: 200
100 | contentType: application/json
101 | contentSchema:
102 | type: object
103 | properties:
104 | jsonrpc:
105 | const: 2.0
106 | result:
107 | $ref: "#/components/schemas/foo"
108 | id:
109 | type: string
110 |
111 |
--------------------------------------------------------------------------------
/doc/moonwalk.html:
--------------------------------------------------------------------------------
1 |
This contents of this document have been gathered from a combination of the 3.1 specification and proposed changes for Moonwalk. None of the content in this document should be considered as product of consensus. This is a working document for the purposes of getting the mechanics of publishing a document in place and beginning to discuss the overall structure of the document.
208 |
209 |
210 |
Abstract
211 |
212 |
213 |
The OpenAPI Specification (OAS) defines a standard, programming language-agnostic interface description for HTTP APIs, which allows both humans and computers to discover and understand the capabilities of a service without requiring access to source code, additional documentation, or inspection of network traffic. When properly defined via OpenAPI, a consumer can understand and interact with the remote service with a minimal amount of implementation logic. Similar to what interface descriptions have done for lower-level programming, the OpenAPI Specification removes guesswork in calling a service.
214 |
215 |
216 |
Conformance
As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.