From 6e129a21a4b2007d9d4d1c2f091cf483e62678c2 Mon Sep 17 00:00:00 2001 From: "Henry H. Andrews" Date: Fri, 28 Feb 2025 07:03:31 -0800 Subject: [PATCH 01/12] Add `$self` for self-identifying documents This adds `$self` as a way for a document to define its own URI for use in reference targets, and as the base URI for relative URI references in the document. This does not impact the resolution of relative API URLs. --- src/oas.md | 9 ++++++--- src/schemas/validation/schema.yaml | 3 +++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/oas.md b/src/oas.md index 11c31c829c..bc0d9be92e 100644 --- a/src/oas.md +++ b/src/oas.md @@ -310,8 +310,10 @@ Unless specified otherwise, all fields that are URIs MAY be relative references Relative references in [Schema Objects](#schema-object), including any that appear as `$id` values, use the nearest parent `$id` as a Base URI, as described by [JSON Schema Specification Draft 2020-12](https://www.ietf.org/archive/id/draft-bhutton-json-schema-01.html#section-8.2). -Relative URI references in other Objects, and in Schema Objects where no parent schema contains an `$id`, MUST be resolved using the referring document's base URI, which is determined in accordance with [[RFC3986]] [Section 5.1.2 – 5.1.4](https://tools.ietf.org/html/rfc3986#section-5.1.2). +Relative URI references in other Objects, and in Schema Objects where no parent schema contains an `$id`, MUST be resolved using the `$self` field of the [OpenAPI Object](#openapi-object). +If no `$self` field is present relative URI references MUST be resolved using the referring document's base URI, which is determined in accordance with [[RFC3986]] [Section 5.1.2 – 5.1.4](https://tools.ietf.org/html/rfc3986#section-5.1.2). In practice, this is usually the retrieval URI of the document, which MAY be determined based on either its current actual location or a user-supplied expected location. +The document's base URI MUST also be used to resolve a relative `$self` URI reference. If a URI contains a fragment identifier, then the fragment should be resolved per the fragment resolution mechanism of the referenced document. If the representation of the referenced document is JSON or YAML, then the fragment identifier SHOULD be interpreted as a JSON-Pointer as per [RFC6901](https://tools.ietf.org/html/rfc6901). @@ -322,7 +324,7 @@ Relative references in CommonMark hyperlinks are resolved in their rendered cont API endpoints are by definition accessed as locations, and are described by this specification as **_URLs_**. Unless specified otherwise, all fields that are URLs MAY be relative references as defined by [RFC3986](https://tools.ietf.org/html/rfc3986#section-4.2). -Unless specified otherwise, relative references are resolved using the URLs defined in the [Server Object](#server-object) as a Base URL. Note that these themselves MAY be relative to the referring document. +Unless specified otherwise, relative references are resolved using the URLs defined in the [Server Object](#server-object) as a Base URL. Note that these themselves MAY be relative to the referring document (**NOT** the [OpenAPI Object's](#openapi-object) `$self` field). ### Schema @@ -342,6 +344,7 @@ This is the root object of the [OpenAPI Description](#openapi-description). | Field Name | Type | Description | | ---- | :----: | ---- | | openapi | `string` | **REQUIRED**. This string MUST be the [version number](#versions) of the OpenAPI Specification that the OpenAPI Document uses. The `openapi` field SHOULD be used by tooling to interpret the OpenAPI Document. This is _not_ related to the API [`info.version`](#info-version) string. | +| $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 (even if the fragment is empty). Implementations MUST support referencing a document by the resolved URI defined by this field. | | info | [Info Object](#info-object) | **REQUIRED**. Provides metadata about the API. The metadata MAY be used by tooling as required. | | jsonSchemaDialect | `string` | The default value for the `$schema` keyword within [Schema Objects](#schema-object) contained within this OAS document. This MUST be in the form of a URI. | | servers | [[Server Object](#server-object)] | An array of Server Objects, which provide connectivity information to a target server. If the `servers` field is not provided, or is an empty array, the default value would be a [Server Object](#server-object) with a [url](#server-url) value of `/`. | @@ -475,7 +478,7 @@ An object representing a Server. | Field Name | Type | Description | | ---- | :----: | ---- | -| url | `string` | **REQUIRED**. A URL to the target host. This URL supports Server Variables and MAY be relative, to indicate that the host location is relative to the location where the document containing the Server Object is being served. Variable substitutions will be made when a variable is named in `{`braces`}`. | +| url | `string` | **REQUIRED**. A URL to the target host. This URL supports Server Variables and MAY be relative, to indicate that the host location is relative to the location where the document containing the Server Object is being served. Variable substitutions will be made when a variable is named in `{`braces`}`. Note that the [OpenAPI Object's](#openapi-object) `$self` field is **NOT** used for relative URL reference resolution. | | description | `string` | An optional string describing the host designated by the URL. [CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text representation. | | name | `string` | An optional unique string to refer to the host designated by the URL. | | variables | Map[`string`, [Server Variable Object](#server-variable-object)] | A map between a variable name and its value. The value is used for substitution in the server's URL template. | diff --git a/src/schemas/validation/schema.yaml b/src/schemas/validation/schema.yaml index 3f804ad16b..696a3bc63d 100644 --- a/src/schemas/validation/schema.yaml +++ b/src/schemas/validation/schema.yaml @@ -8,6 +8,9 @@ properties: openapi: type: string pattern: '^3\.2\.\d+(-.+)?$' + $self: + type: string + format: uri-reference info: $ref: '#/$defs/info' jsonSchemaDialect: From 604789fd8ca20fb52273ce96aaf4e0830163b7a5 Mon Sep 17 00:00:00 2001 From: "Henry H. Andrews" Date: Wed, 19 Mar 2025 12:24:15 -0700 Subject: [PATCH 02/12] Rework and include examples. --- src/oas.md | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 79 insertions(+), 5 deletions(-) diff --git a/src/oas.md b/src/oas.md index bc0d9be92e..b7e9863114 100644 --- a/src/oas.md +++ b/src/oas.md @@ -308,15 +308,69 @@ Note that some URI fields are named `url` for historical reasons, but the descri Unless specified otherwise, all fields that are URIs MAY be relative references as defined by [RFC3986](https://tools.ietf.org/html/rfc3986#section-4.2). -Relative references in [Schema Objects](#schema-object), including any that appear as `$id` values, use the nearest parent `$id` as a Base URI, as described by [JSON Schema Specification Draft 2020-12](https://www.ietf.org/archive/id/draft-bhutton-json-schema-01.html#section-8.2). +#### Establishing the Base URI -Relative URI references in other Objects, and in Schema Objects where no parent schema contains an `$id`, MUST be resolved using the `$self` field of the [OpenAPI Object](#openapi-object). -If no `$self` field is present relative URI references MUST be resolved using the referring document's base URI, which is determined in accordance with [[RFC3986]] [Section 5.1.2 – 5.1.4](https://tools.ietf.org/html/rfc3986#section-5.1.2). -In practice, this is usually the retrieval URI of the document, which MAY be determined based on either its current actual location or a user-supplied expected location. -The document's base URI MUST also be used to resolve a relative `$self` URI reference. +Relative URI references are resolved using the appropriate base URI, which MUST be determined in accordance with [[RFC3986]] [Section 5.1.1 – 5.1.4](https://tools.ietf.org/html/rfc3986#section-5.1.1). +RFC3986 Section 5.1.1 requires determining the base URI from within a resource's contents, which for the OAS means the `$self` field of the [OpenAPI Object](#openapi-object) for an [OpenAPI Document](#openapi-document), or the `$id` JSON Schema keyword in [Schema Objects](#schema-object). +Within an OpenAPI Document, a Schema Object that does not have its base URI set by `$id` uses `$self` the same as any other Object, treating the OpenAPI Document as the "encapsulating entity" in accordance with RFC3986 Section 5.1.2. +See [JSON Schema draft 2020-12 Section 8.2](https://www.ietf.org/archive/id/draft-bhutton-json-schema-01.html#section-8.2) for more information about base URIs in Schema Objects. + +The most common base URI source in the absence of `$self` or `$id` is the retrieval URI, in accordance with RFC3986 Section 5.1.3. +Since not all tools support direct retrieval, and because direct retrieval is sometimes prevented by network conditions or security policies, tools SHOULD allow users to provide the intended retrieval URI along with the document. + +Note that these rules mean that different fields in the document, particularly those in Schema Objects vs other kinds of Objects, can have different base URIs. +Relative URI references in `$self` or `$id` are resolved against the base URI appropriate for their location in the document. + +Base URIs for documents containing OpenAPI content without an OpenAPI Object at the root ignore the `$self` rule, as no `$self` can be present in such documents. + +##### Examples of Base URI Determination + +Given a retrieval URI of `https://example.com/foo/bar/openapi.yaml`, and the following OpenAPI Document: + +```YAML +openapi: 3.2.0 +$self: /openapi +info: + version: 1.0 +components: + pathItems: + Foo: + $ref: "./shared#/components/pathItems/Foo" +``` + +1. The base URI used to resolve `$self` is the retrieval URI, resulting in an effective `$self` value of `https://example.com/openapi` (OADs that use HTTP content negotiation to provide both JSON and YAML representations typically do not use a file extension in their self-assigned URI, to avoid needing to change URIs based on the format). +2. The base URI for the `$ref` comes from `$self` (`https://example.com/openapi`), producing a resolved URI of `https://example.com/shared#/components/pathItems/Foo` + +Relative `$self` values are often used for APIs deployed in multiple locations, such as a device management API that is hosted on each device. + +In the next example, the retrieval URI is irrelevant, because `$self` is already a full URI: + +```YAML +openapi: 3.2.0 +$self: https://example.com/openapi +info: + version: 1.0 +components: + schemas: + Foo: + $id: ./schemas/foo + properties: + bar: + $ref: bar + Bar: + $id: ./schemas/bar +``` + +In this example, both Schema Objects use `https://example.com/openapi` as their base URI for resolving their relative `$id` values to `https://example.com/foo` and `https://example.com/bar`. The `$ref` under `properties` is resolved against the `$id`-provided base URI `https://example.com/foo`, producing `https://example.com/bar`, which is the `$id`-assigned URI of the Bar schema component. + +Note that using embedded `$id` keywords prevents using `$ref: "#/components/schemas/Bar"` in the `properties` field's `$ref` because the base URI for such fragments is set by the `$id`. Therefore, a `$ref: "#/components/schemas/Bar"` would resolve to `"https://example.com/schemas/foo#/components/schemas/Bar"`, which is not useful. + +#### Resolving URI fragments If a URI contains a fragment identifier, then the fragment should be resolved per the fragment resolution mechanism of the referenced document. If the representation of the referenced document is JSON or YAML, then the fragment identifier SHOULD be interpreted as a JSON-Pointer as per [RFC6901](https://tools.ietf.org/html/rfc6901). +#### Relative URI References in CommonMark Fields + Relative references in CommonMark hyperlinks are resolved in their rendered context, which might differ from the context of the API description. ### Relative References in API URLs @@ -326,6 +380,24 @@ API endpoints are by definition accessed as locations, and are described by this Unless specified otherwise, all fields that are URLs MAY be relative references as defined by [RFC3986](https://tools.ietf.org/html/rfc3986#section-4.2). Unless specified otherwise, relative references are resolved using the URLs defined in the [Server Object](#server-object) as a Base URL. Note that these themselves MAY be relative to the referring document (**NOT** the [OpenAPI Object's](#openapi-object) `$self` field). +#### Examples of API Base URL Determination + +Assume a retrieval URL of `https://device1.example.com` for the following OpenAPI Document: + +```YAML +openapi: 3.2.0 +$self: https://apidescriptions.example.com/foo +info: + version: 1.0 +servers: +- url: . + description: The production API on this device +- url: ./test + description: The test API on this device +``` + +For API URLs, the `$self` field, which identifies the OpenAPI Document, is ignored, and the retrieval URL is used instead. This produces a normalized production URL of `https://device1.example.com`, and a normalized test URL of `https://device1.example.com/test`. + ### Schema This section describes the structure of the OpenAPI Description format. @@ -487,6 +559,8 @@ This object MAY be extended with [Specification Extensions](#specification-exten ##### Server Object Example +See also [Examples of API Base URL Determination](#examples-of-api-base-url-determination) for examples of resolving relative server URLs. + A single server would be described as: ```json From 5e3c600555407bfa66c45713cd90c1b69244977e Mon Sep 17 00:00:00 2001 From: Henry Andrews Date: Fri, 21 Mar 2025 09:24:57 -0700 Subject: [PATCH 03/12] Fix example Co-authored-by: Ralf Handl --- src/oas.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/oas.md b/src/oas.md index b7e9863114..7a011f0c5d 100644 --- a/src/oas.md +++ b/src/oas.md @@ -361,7 +361,7 @@ components: $id: ./schemas/bar ``` -In this example, both Schema Objects use `https://example.com/openapi` as their base URI for resolving their relative `$id` values to `https://example.com/foo` and `https://example.com/bar`. The `$ref` under `properties` is resolved against the `$id`-provided base URI `https://example.com/foo`, producing `https://example.com/bar`, which is the `$id`-assigned URI of the Bar schema component. +In this example, both Schema Objects use `https://example.com/openapi` as their base URI for resolving their relative `$id` values to `https://example.com/schemas/foo` and `https://example.com/schemas/bar`. The `$ref` under `properties` is resolved against the `$id`-provided base URI `https://example.com/schemas/foo`, producing `https://example.com/schemas/bar`, which is the `$id`-assigned URI of the Bar schema component. Note that using embedded `$id` keywords prevents using `$ref: "#/components/schemas/Bar"` in the `properties` field's `$ref` because the base URI for such fragments is set by the `$id`. Therefore, a `$ref: "#/components/schemas/Bar"` would resolve to `"https://example.com/schemas/foo#/components/schemas/Bar"`, which is not useful. From f469211055eb6a30426929ae0578d7075f929e78 Mon Sep 17 00:00:00 2001 From: "Henry H. Andrews" Date: Fri, 21 Mar 2025 09:24:10 -0700 Subject: [PATCH 04/12] Make schema check more precise for $self Co-authored by: Karen Etheridge --- src/schemas/validation/schema.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/schemas/validation/schema.yaml b/src/schemas/validation/schema.yaml index 696a3bc63d..fe3554a26d 100644 --- a/src/schemas/validation/schema.yaml +++ b/src/schemas/validation/schema.yaml @@ -11,6 +11,8 @@ properties: $self: type: string format: uri-reference + $comment: MUST NOT be empty, and MUST NOT contain a fragment + pattern: '^[^#]+$' info: $ref: '#/$defs/info' jsonSchemaDialect: From 43cb4642887f1a2cbc27cf1e756b3a65a26a9025 Mon Sep 17 00:00:00 2001 From: Henry Andrews Date: Wed, 26 Mar 2025 13:18:11 -0700 Subject: [PATCH 05/12] Apply suggestions from code review Co-authored-by: Karen Etheridge --- src/oas.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/oas.md b/src/oas.md index 7a011f0c5d..36e91d8f3b 100644 --- a/src/oas.md +++ b/src/oas.md @@ -339,7 +339,7 @@ components: ``` 1. The base URI used to resolve `$self` is the retrieval URI, resulting in an effective `$self` value of `https://example.com/openapi` (OADs that use HTTP content negotiation to provide both JSON and YAML representations typically do not use a file extension in their self-assigned URI, to avoid needing to change URIs based on the format). -2. The base URI for the `$ref` comes from `$self` (`https://example.com/openapi`), producing a resolved URI of `https://example.com/shared#/components/pathItems/Foo` +2. The base URI for the `$ref` comes from `$self` (`https://example.com/openapi`), producing a resolved URI of `https://example.com/shared#/components/pathItems/Foo`. Relative `$self` values are often used for APIs deployed in multiple locations, such as a device management API that is hosted on each device. @@ -363,7 +363,7 @@ components: In this example, both Schema Objects use `https://example.com/openapi` as their base URI for resolving their relative `$id` values to `https://example.com/schemas/foo` and `https://example.com/schemas/bar`. The `$ref` under `properties` is resolved against the `$id`-provided base URI `https://example.com/schemas/foo`, producing `https://example.com/schemas/bar`, which is the `$id`-assigned URI of the Bar schema component. -Note that using embedded `$id` keywords prevents using `$ref: "#/components/schemas/Bar"` in the `properties` field's `$ref` because the base URI for such fragments is set by the `$id`. Therefore, a `$ref: "#/components/schemas/Bar"` would resolve to `"https://example.com/schemas/foo#/components/schemas/Bar"`, which is not useful. +Note that using embedded `$id` keywords would prevent using `$ref: "#/components/schemas/Bar"` in the `properties` field's `$ref` because the base URI for such fragments is set by the `$id`. Therefore, a `$ref: "#/components/schemas/Bar"` would resolve to `"https://example.com/schemas/foo#/components/schemas/Bar"`, which is not the presumably-intended location. #### Resolving URI fragments From 1294a8643f609b0d8231d9ed84ea92c9db40632e Mon Sep 17 00:00:00 2001 From: "Henry H. Andrews" Date: Wed, 26 Mar 2025 13:39:02 -0700 Subject: [PATCH 06/12] Further clarifications from review. This ties the `$self` behavior more directly to the sections on API Description URI usage, including examples, and also expands on the use cases for manually providing a retrieval URI. --- src/oas.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/oas.md b/src/oas.md index 36e91d8f3b..1c7a9cc2a7 100644 --- a/src/oas.md +++ b/src/oas.md @@ -316,14 +316,20 @@ Within an OpenAPI Document, a Schema Object that does not have its base URI set See [JSON Schema draft 2020-12 Section 8.2](https://www.ietf.org/archive/id/draft-bhutton-json-schema-01.html#section-8.2) for more information about base URIs in Schema Objects. The most common base URI source in the absence of `$self` or `$id` is the retrieval URI, in accordance with RFC3986 Section 5.1.3. -Since not all tools support direct retrieval, and because direct retrieval is sometimes prevented by network conditions or security policies, tools SHOULD allow users to provide the intended retrieval URI along with the document. Note that these rules mean that different fields in the document, particularly those in Schema Objects vs other kinds of Objects, can have different base URIs. Relative URI references in `$self` or `$id` are resolved against the base URI appropriate for their location in the document. +Implementations SHOULD allow users to provide the intended retrieval URI along with each document, as this is necessary in situations including: + +* Implementations that do not support direct retrieval, which requires additional dependencies and security considerations +* Network configurations or conditions that prevent direct retrieval +* Test configurations that need to simulate the document being hosted in a production location +* Documents that exist only in-memory and have no readily identifiable location (although for a single document without references to other documents, an application-specific default base URI in accordance with RFC3986 Section 5.1.4 would also be suitable) + Base URIs for documents containing OpenAPI content without an OpenAPI Object at the root ignore the `$self` rule, as no `$self` can be present in such documents. -##### Examples of Base URI Determination +##### Examples of Base URI Determination and Reference Resolution Given a retrieval URI of `https://example.com/foo/bar/openapi.yaml`, and the following OpenAPI Document: @@ -363,7 +369,7 @@ components: In this example, both Schema Objects use `https://example.com/openapi` as their base URI for resolving their relative `$id` values to `https://example.com/schemas/foo` and `https://example.com/schemas/bar`. The `$ref` under `properties` is resolved against the `$id`-provided base URI `https://example.com/schemas/foo`, producing `https://example.com/schemas/bar`, which is the `$id`-assigned URI of the Bar schema component. -Note that using embedded `$id` keywords would prevent using `$ref: "#/components/schemas/Bar"` in the `properties` field's `$ref` because the base URI for such fragments is set by the `$id`. Therefore, a `$ref: "#/components/schemas/Bar"` would resolve to `"https://example.com/schemas/foo#/components/schemas/Bar"`, which is not the presumably-intended location. +Note that using embedded `$id` keywords would prevent using `$ref: "#/components/schemas/Bar"` in the `properties` field's `$ref` because the base URI for such fragments is set by the `$id`. Therefore, a `$ref: "#/components/schemas/Bar"` would resolve to `"https://example.com/schemas/foo#/components/schemas/Bar"`, rather than the presumably-intended location of `"https://example.com/openapi#/components/schemas/Bar"`. #### Resolving URI fragments @@ -416,7 +422,7 @@ This is the root object of the [OpenAPI Description](#openapi-description). | Field Name | Type | Description | | ---- | :----: | ---- | | openapi | `string` | **REQUIRED**. This string MUST be the [version number](#versions) of the OpenAPI Specification that the OpenAPI Document uses. The `openapi` field SHOULD be used by tooling to interpret the OpenAPI Document. This is _not_ related to the API [`info.version`](#info-version) string. | -| $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 (even if the fragment is empty). Implementations MUST support referencing a document by the resolved URI defined by this field. | +| $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 (even if the fragment is empty). Implementations MUST support identifying the targets of [API description URIs](#relative-references-in-api-description-uris) using the resolved URI defined by this field, as shown under [Examples of Base URI Determination and Reference Resolution](#examples-of-base-uri-determination-and-reference-resolution).| | info | [Info Object](#info-object) | **REQUIRED**. Provides metadata about the API. The metadata MAY be used by tooling as required. | | jsonSchemaDialect | `string` | The default value for the `$schema` keyword within [Schema Objects](#schema-object) contained within this OAS document. This MUST be in the form of a URI. | | servers | [[Server Object](#server-object)] | An array of Server Objects, which provide connectivity information to a target server. If the `servers` field is not provided, or is an empty array, the default value would be a [Server Object](#server-object) with a [url](#server-url) value of `/`. | From 2e5bfbc3eca485ebb666920bf0a666050bd6930f Mon Sep 17 00:00:00 2001 From: Henry Andrews Date: Wed, 2 Apr 2025 11:57:35 -0700 Subject: [PATCH 07/12] Apply suggestions from code review Co-authored-by: Ralf Handl --- src/oas.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/oas.md b/src/oas.md index 1c7a9cc2a7..21ba9925e9 100644 --- a/src/oas.md +++ b/src/oas.md @@ -369,7 +369,7 @@ components: In this example, both Schema Objects use `https://example.com/openapi` as their base URI for resolving their relative `$id` values to `https://example.com/schemas/foo` and `https://example.com/schemas/bar`. The `$ref` under `properties` is resolved against the `$id`-provided base URI `https://example.com/schemas/foo`, producing `https://example.com/schemas/bar`, which is the `$id`-assigned URI of the Bar schema component. -Note that using embedded `$id` keywords would prevent using `$ref: "#/components/schemas/Bar"` in the `properties` field's `$ref` because the base URI for such fragments is set by the `$id`. Therefore, a `$ref: "#/components/schemas/Bar"` would resolve to `"https://example.com/schemas/foo#/components/schemas/Bar"`, rather than the presumably-intended location of `"https://example.com/openapi#/components/schemas/Bar"`. +Note that using embedded `$id` keywords would prevent using `$ref: "#/components/schemas/Bar"` in the `properties` keyword's `$ref` because the base URI for such fragments is set by the `$id`. Therefore, a `$ref: "#/components/schemas/Bar"` would resolve to `"https://example.com/schemas/foo#/components/schemas/Bar"`, rather than the presumably-intended location of `"https://example.com/openapi#/components/schemas/Bar"`. #### Resolving URI fragments @@ -422,7 +422,7 @@ This is the root object of the [OpenAPI Description](#openapi-description). | Field Name | Type | Description | | ---- | :----: | ---- | | openapi | `string` | **REQUIRED**. This string MUST be the [version number](#versions) of the OpenAPI Specification that the OpenAPI Document uses. The `openapi` field SHOULD be used by tooling to interpret the OpenAPI Document. This is _not_ related to the API [`info.version`](#info-version) string. | -| $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 (even if the fragment is empty). Implementations MUST support identifying the targets of [API description URIs](#relative-references-in-api-description-uris) using the resolved URI defined by this field, as shown under [Examples of Base URI Determination and Reference Resolution](#examples-of-base-uri-determination-and-reference-resolution).| +| $self | `URI-reference` (without a fragment) | Sets the URI of this document, which also serves as its base URI in accordance with [[RFC3986]] [Section 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 (even if the fragment is empty). Implementations MUST support identifying the targets of [API description URIs](#relative-references-in-api-description-uris) using the resolved URI defined by this field, as shown under [Examples of Base URI Determination and Reference Resolution](#examples-of-base-uri-determination-and-reference-resolution).| | info | [Info Object](#info-object) | **REQUIRED**. Provides metadata about the API. The metadata MAY be used by tooling as required. | | jsonSchemaDialect | `string` | The default value for the `$schema` keyword within [Schema Objects](#schema-object) contained within this OAS document. This MUST be in the form of a URI. | | servers | [[Server Object](#server-object)] | An array of Server Objects, which provide connectivity information to a target server. If the `servers` field is not provided, or is an empty array, the default value would be a [Server Object](#server-object) with a [url](#server-url) value of `/`. | From e0a2cb6b3da0671142c7b4b277ccc4aa419deee5 Mon Sep 17 00:00:00 2001 From: "Henry H. Andrews" Date: Wed, 2 Apr 2025 12:01:51 -0700 Subject: [PATCH 08/12] Align type field for `$self` with style guide. Also tweak the wording a bit as a result, and ran format-markdown. --- src/oas.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/oas.md b/src/oas.md index 21ba9925e9..1306028384 100644 --- a/src/oas.md +++ b/src/oas.md @@ -367,9 +367,9 @@ components: $id: ./schemas/bar ``` -In this example, both Schema Objects use `https://example.com/openapi` as their base URI for resolving their relative `$id` values to `https://example.com/schemas/foo` and `https://example.com/schemas/bar`. The `$ref` under `properties` is resolved against the `$id`-provided base URI `https://example.com/schemas/foo`, producing `https://example.com/schemas/bar`, which is the `$id`-assigned URI of the Bar schema component. +In this example, both Schema Objects use `https://example.com/openapi` as their base URI for resolving their relative `$id` values to `https://example.com/schemas/foo` and `https://example.com/schemas/bar`. The `$ref` under `properties` is resolved against the `$id`-provided base URI `https://example.com/schemas/foo`, producing `https://example.com/schemas/bar`, which is the `$id`-assigned URI of the Bar schema component. -Note that using embedded `$id` keywords would prevent using `$ref: "#/components/schemas/Bar"` in the `properties` keyword's `$ref` because the base URI for such fragments is set by the `$id`. Therefore, a `$ref: "#/components/schemas/Bar"` would resolve to `"https://example.com/schemas/foo#/components/schemas/Bar"`, rather than the presumably-intended location of `"https://example.com/openapi#/components/schemas/Bar"`. +Note that using embedded `$id` keywords would prevent using `$ref: "#/components/schemas/Bar"` in the `properties` keyword's `$ref` because the base URI for such fragments is set by the `$id`. Therefore, a `$ref: "#/components/schemas/Bar"` would resolve to `"https://example.com/schemas/foo#/components/schemas/Bar"`, rather than the presumably-intended location of `"https://example.com/openapi#/components/schemas/Bar"`. #### Resolving URI fragments @@ -402,7 +402,7 @@ servers: description: The test API on this device ``` -For API URLs, the `$self` field, which identifies the OpenAPI Document, is ignored, and the retrieval URL is used instead. This produces a normalized production URL of `https://device1.example.com`, and a normalized test URL of `https://device1.example.com/test`. +For API URLs, the `$self` field, which identifies the OpenAPI Document, is ignored, and the retrieval URL is used instead. This produces a normalized production URL of `https://device1.example.com`, and a normalized test URL of `https://device1.example.com/test`. ### Schema @@ -422,7 +422,7 @@ This is the root object of the [OpenAPI Description](#openapi-description). | Field Name | Type | Description | | ---- | :----: | ---- | | openapi | `string` | **REQUIRED**. This string MUST be the [version number](#versions) of the OpenAPI Specification that the OpenAPI Document uses. The `openapi` field SHOULD be used by tooling to interpret the OpenAPI Document. This is _not_ related to the API [`info.version`](#info-version) string. | -| $self | `URI-reference` (without a fragment) | Sets the URI of this document, which also serves as its base URI in accordance with [[RFC3986]] [Section 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 (even if the fragment is empty). Implementations MUST support identifying the targets of [API description URIs](#relative-references-in-api-description-uris) using the resolved URI defined by this field, as shown under [Examples of Base URI Determination and Reference Resolution](#examples-of-base-uri-determination-and-reference-resolution).| +| $self | `string` | This string MUST be in the form of a URI-reference, MUST NOT be an empty string, and MUST NOT contain a fragment (empty or otherwise). The `$self` field provides the self-assigned URI of this document, which also serves as its base URI in accordance with [[RFC3986]] [Section 5.1.1](https://www.rfc-editor.org/rfc/rfc3986#section-5.1.1). Implementations MUST support identifying the targets of [API description URIs](#relative-references-in-api-description-uris) using the resolved URI defined by this field, as shown under [Examples of Base URI Determination and Reference Resolution](#examples-of-base-uri-determination-and-reference-resolution). | | info | [Info Object](#info-object) | **REQUIRED**. Provides metadata about the API. The metadata MAY be used by tooling as required. | | jsonSchemaDialect | `string` | The default value for the `$schema` keyword within [Schema Objects](#schema-object) contained within this OAS document. This MUST be in the form of a URI. | | servers | [[Server Object](#server-object)] | An array of Server Objects, which provide connectivity information to a target server. If the `servers` field is not provided, or is an empty array, the default value would be a [Server Object](#server-object) with a [url](#server-url) value of `/`. | @@ -556,7 +556,7 @@ An object representing a Server. | Field Name | Type | Description | | ---- | :----: | ---- | -| url | `string` | **REQUIRED**. A URL to the target host. This URL supports Server Variables and MAY be relative, to indicate that the host location is relative to the location where the document containing the Server Object is being served. Variable substitutions will be made when a variable is named in `{`braces`}`. Note that the [OpenAPI Object's](#openapi-object) `$self` field is **NOT** used for relative URL reference resolution. | +| url | `string` | **REQUIRED**. A URL to the target host. This URL supports Server Variables and MAY be relative, to indicate that the host location is relative to the location where the document containing the Server Object is being served. Variable substitutions will be made when a variable is named in `{`braces`}`. Note that the [OpenAPI Object's](#openapi-object) `$self` field is **NOT** used for relative URL reference resolution. | | description | `string` | An optional string describing the host designated by the URL. [CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text representation. | | name | `string` | An optional unique string to refer to the host designated by the URL. | | variables | Map[`string`, [Server Variable Object](#server-variable-object)] | A map between a variable name and its value. The value is used for substitution in the server's URL template. | From d68683c46cd8f998eb598ce18df96e25dfa105ba Mon Sep 17 00:00:00 2001 From: Henry Andrews Date: Wed, 2 Apr 2025 14:13:33 -0700 Subject: [PATCH 09/12] Review feedback Co-authored-by: Ralf Handl --- src/oas.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/oas.md b/src/oas.md index 1306028384..2f4676fca5 100644 --- a/src/oas.md +++ b/src/oas.md @@ -367,7 +367,7 @@ components: $id: ./schemas/bar ``` -In this example, both Schema Objects use `https://example.com/openapi` as their base URI for resolving their relative `$id` values to `https://example.com/schemas/foo` and `https://example.com/schemas/bar`. The `$ref` under `properties` is resolved against the `$id`-provided base URI `https://example.com/schemas/foo`, producing `https://example.com/schemas/bar`, which is the `$id`-assigned URI of the Bar schema component. +In this example, both Schema Objects use `https://example.com/openapi` as their base URI for resolving their relative `$id` values to `https://example.com/schemas/foo` and `https://example.com/schemas/bar`. The `$ref` under `properties` is resolved against the `$id`-provided base URI `https://example.com/schemas/foo`, producing `https://example.com/schemas/bar`, which is the `$id`-assigned URI of the `Bar` schema component. Note that using embedded `$id` keywords would prevent using `$ref: "#/components/schemas/Bar"` in the `properties` keyword's `$ref` because the base URI for such fragments is set by the `$id`. Therefore, a `$ref: "#/components/schemas/Bar"` would resolve to `"https://example.com/schemas/foo#/components/schemas/Bar"`, rather than the presumably-intended location of `"https://example.com/openapi#/components/schemas/Bar"`. From 7568b58a1e0267f1651e31e9c75f93c561ece728 Mon Sep 17 00:00:00 2001 From: "Henry H. Andrews" Date: Thu, 3 Apr 2025 19:06:34 -0700 Subject: [PATCH 10/12] Review feedback from @notEthan --- src/oas.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/oas.md b/src/oas.md index 2f4676fca5..2b5160b194 100644 --- a/src/oas.md +++ b/src/oas.md @@ -312,7 +312,7 @@ Unless specified otherwise, all fields that are URIs MAY be relative references Relative URI references are resolved using the appropriate base URI, which MUST be determined in accordance with [[RFC3986]] [Section 5.1.1 – 5.1.4](https://tools.ietf.org/html/rfc3986#section-5.1.1). RFC3986 Section 5.1.1 requires determining the base URI from within a resource's contents, which for the OAS means the `$self` field of the [OpenAPI Object](#openapi-object) for an [OpenAPI Document](#openapi-document), or the `$id` JSON Schema keyword in [Schema Objects](#schema-object). -Within an OpenAPI Document, a Schema Object that does not have its base URI set by `$id` uses `$self` the same as any other Object, treating the OpenAPI Document as the "encapsulating entity" in accordance with RFC3986 Section 5.1.2. +Within an OpenAPI Document, a Schema Object that does not have its base URI set by `$id` takes its base URI from the OpenAPI Object's `$self` field the same as any other Object, treating the OpenAPI Document as the "encapsulating entity" in accordance with RFC3986 Section 5.1.2. See [JSON Schema draft 2020-12 Section 8.2](https://www.ietf.org/archive/id/draft-bhutton-json-schema-01.html#section-8.2) for more information about base URIs in Schema Objects. The most common base URI source in the absence of `$self` or `$id` is the retrieval URI, in accordance with RFC3986 Section 5.1.3. @@ -337,6 +337,7 @@ Given a retrieval URI of `https://example.com/foo/bar/openapi.yaml`, and the fol openapi: 3.2.0 $self: /openapi info: + title: Example API version: 1.0 components: pathItems: @@ -355,6 +356,7 @@ In the next example, the retrieval URI is irrelevant, because `$self` is already openapi: 3.2.0 $self: https://example.com/openapi info: + title: Example API version: 1.0 components: schemas: @@ -394,6 +396,7 @@ Assume a retrieval URL of `https://device1.example.com` for the following OpenAP openapi: 3.2.0 $self: https://apidescriptions.example.com/foo info: + title: Example API version: 1.0 servers: - url: . From 34fb6d61c1b40688fed84b90a51c36387b3c96af Mon Sep 17 00:00:00 2001 From: "Henry H. Andrews" Date: Thu, 10 Apr 2025 10:30:53 -0700 Subject: [PATCH 11/12] Better URI terminology, I hope --- src/oas.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/oas.md b/src/oas.md index 2b5160b194..2c1f177226 100644 --- a/src/oas.md +++ b/src/oas.md @@ -350,7 +350,7 @@ components: Relative `$self` values are often used for APIs deployed in multiple locations, such as a device management API that is hosted on each device. -In the next example, the retrieval URI is irrelevant, because `$self` is already a full URI: +In the next example, the retrieval URI is irrelevant, because `$self` is already a fully resolved URI rather than a relative URI-reference: ```YAML openapi: 3.2.0 From 8d1c6be24713c1a3ff38641416dcdcb671495749 Mon Sep 17 00:00:00 2001 From: "Henry H. Andrews" Date: Wed, 23 Apr 2025 12:27:04 -0700 Subject: [PATCH 12/12] More review feedback --- src/oas.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/oas.md b/src/oas.md index 2c1f177226..6fb292e220 100644 --- a/src/oas.md +++ b/src/oas.md @@ -390,7 +390,7 @@ Unless specified otherwise, relative references are resolved using the URLs defi #### Examples of API Base URL Determination -Assume a retrieval URL of `https://device1.example.com` for the following OpenAPI Document: +Assume a retrieval URI of `https://device1.example.com` for the following OpenAPI Document: ```YAML openapi: 3.2.0 @@ -405,7 +405,7 @@ servers: description: The test API on this device ``` -For API URLs, the `$self` field, which identifies the OpenAPI Document, is ignored, and the retrieval URL is used instead. This produces a normalized production URL of `https://device1.example.com`, and a normalized test URL of `https://device1.example.com/test`. +For API URLs, the `$self` field, which identifies the OpenAPI Document, is ignored, and the retrieval URI is used instead. This produces a normalized production URL of `https://device1.example.com`, and a normalized test URL of `https://device1.example.com/test`. ### Schema @@ -425,7 +425,7 @@ This is the root object of the [OpenAPI Description](#openapi-description). | Field Name | Type | Description | | ---- | :----: | ---- | | openapi | `string` | **REQUIRED**. This string MUST be the [version number](#versions) of the OpenAPI Specification that the OpenAPI Document uses. The `openapi` field SHOULD be used by tooling to interpret the OpenAPI Document. This is _not_ related to the API [`info.version`](#info-version) string. | -| $self | `string` | This string MUST be in the form of a URI-reference, MUST NOT be an empty string, and MUST NOT contain a fragment (empty or otherwise). The `$self` field provides the self-assigned URI of this document, which also serves as its base URI in accordance with [[RFC3986]] [Section 5.1.1](https://www.rfc-editor.org/rfc/rfc3986#section-5.1.1). Implementations MUST support identifying the targets of [API description URIs](#relative-references-in-api-description-uris) using the resolved URI defined by this field, as shown under [Examples of Base URI Determination and Reference Resolution](#examples-of-base-uri-determination-and-reference-resolution). | +| $self | `string` | This string MUST be in the form of a URI-reference, MUST NOT be an empty string, and MUST NOT contain a fragment (empty or otherwise). The `$self` field provides the self-assigned URI of this document, which also serves as its base URI in accordance with [[RFC3986]] [Section 5.1.1](https://www.rfc-editor.org/rfc/rfc3986#section-5.1.1). See [Establishing the Base URI](#establishing-the-base-uri) for handling an absent or relative `$self`. Implementations MUST support identifying the targets of [API description URIs](#relative-references-in-api-description-uris) using the resolved URI defined by this field, as shown under [Examples of Base URI Determination and Reference Resolution](#examples-of-base-uri-determination-and-reference-resolution). | | info | [Info Object](#info-object) | **REQUIRED**. Provides metadata about the API. The metadata MAY be used by tooling as required. | | jsonSchemaDialect | `string` | The default value for the `$schema` keyword within [Schema Objects](#schema-object) contained within this OAS document. This MUST be in the form of a URI. | | servers | [[Server Object](#server-object)] | An array of Server Objects, which provide connectivity information to a target server. If the `servers` field is not provided, or is an empty array, the default value would be a [Server Object](#server-object) with a [url](#server-url) value of `/`. |