diff --git a/.spectral-required.yml b/.spectral-required.yml
index a7f8528..521fc63 100644
--- a/.spectral-required.yml
+++ b/.spectral-required.yml
@@ -98,6 +98,19 @@ rules:
functionOptions:
match: ^[a-z0-9]+(-[a-z0-9]+)*$
+ entur-info-metadata-devExtensions:
+ documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#244-development-only-openapi-extensions"
+ severity: error
+ given: $.info.x-entur-metadata.devExtensions
+ then:
+ function: schema
+ functionOptions:
+ schema:
+ type: array
+ items:
+ type: string
+ pattern: ^x-.*$
+
# -------------------------------------------------------------------------
# 2.5 Lifecycle
# -------------------------------------------------------------------------
diff --git a/.spectral.yml b/.spectral.yml
index a4f333f..aec93ff 100644
--- a/.spectral.yml
+++ b/.spectral.yml
@@ -244,6 +244,19 @@ rules:
functionOptions:
match: ^[a-z0-9]+(-[a-z0-9]+)*$
+ entur-info-metadata-devExtensions:
+ documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#244-development-only-openapi-extensions"
+ severity: error
+ given: $.info.x-entur-metadata.devExtensions
+ then:
+ function: schema
+ functionOptions:
+ schema:
+ type: array
+ items:
+ type: string
+ pattern: ^x-.*$
+
# -------------------------------------------------------------------------
# 2.5 Lifecycle
# -------------------------------------------------------------------------
diff --git a/guidelines.md b/guidelines.md
index 451c9ea..9e88bba 100644
--- a/guidelines.md
+++ b/guidelines.md
@@ -174,12 +174,13 @@ If you need to explain the required permissions in more detail, you can declare
### 2.4 Entur Metadata
All OpenAPI specifications published to Enturs developer portal must declare a block `x-entur-metadata` in the `info` section of the specification.
-Field name|Type |Description
-----------|--------|-----------
-id |`string`|**REQUIRED**. Unique id for this specification. [Read more](#241-identifying-a-specification).
-audience |`string`|**REQUIRED**. Who this specification is targeted to. Must be one of `"open"`, `"partner"`, `"internal"`, `"private"`
-owner |`string`|**REQUIRED**. The Entur team responsible for this specification. [Read more](#242-specification-owner).
-parentId |`string`|Id of the parent specification, used when merging. [Read more](#243-merging-specifications).
+Field name |Type |Description
+--------------|----------|-----------
+id |`string` |**REQUIRED**. Unique id for this specification. [Read more](#241-identifying-a-specification).
+audience |`string` |**REQUIRED**. Who this specification is targeted to. Must be one of `"open"`, `"partner"`, `"internal"`, `"private"`
+owner |`string` |**REQUIRED**. The Entur team responsible for this specification. [Read more](#242-specification-owner).
+parentId |`string` |Id of the parent specification, used when merging. [Read more](#243-merging-specifications).
+devExtensions |[`string`]|OpenAPI extensions in the specification that are used for development, but that should not be visible to consumers of the API.
Example:
```json
@@ -229,6 +230,7 @@ There are some limitations when merging specifications:
Example
+
For example, say you have three microservices, `alpha`, `beta` and `gamma`:
Microservice `alpha` publishes the specification:
@@ -270,6 +272,35 @@ Microservice `gamma` publishes the specification:
Here, only 1 specification will be shown on the Developer Portal, which is a combination of `alpha`, `beta` and `gamma`. Since `alpha` is the parent specification, the combined specification will use `alpha` as the base, so fields like `info.title` will be picked from there.
+#### 2.4.4 Development-only OpenAPI extensions
+Sometimes there may be a need for adding OpenAPI extensions to a specification that are only meant for the development process, for example for generating server interfaces with [OpenAPIGenerator](https://openapi-generator.tech/docs/generators/kotlin-spring#supported-vendor-extensions). These extensions are only relevant for the team creating the API, not for consumers. To hide extensions like these from the OpenAPI specification that is served from the Developer Portal, use the field `x-entur-metadata.devExtensions`.
+
+
+Example
+
+The extension `x-kotlin-implements` will be stripped before the specification is published to the Developer Portal.
+
+```json
+{
+ "info": {
+ "x-entur-metadata": {
+ ...,
+ "devExtensions": ["x-kotlin-implements"]
+ }
+ },
+ "components": {
+ "schemas": {
+ "Item": {
+ "type": "object",
+ "x-kotlin-implements": ["com.example.Item"],
+ ...
+ }
+ }
+ }
+}
+```
+
+
### 2.5 Lifecycle
All APIs, and endpoints within an API, follow a lifecycle with different stages that have different properties. The following sections describe a standardized way to declare an API's lifecycle status in its specification. Following this standard has several benefits:
diff --git a/specs/reference-spec-with-errors.json b/specs/reference-spec-with-errors.json
index 03762d2..0f2468a 100644
--- a/specs/reference-spec-with-errors.json
+++ b/specs/reference-spec-with-errors.json
@@ -12,7 +12,8 @@
},
"x-entur-metadata": {
"owner": "team-Api",
- "audience": "public"
+ "audience": "public",
+ "devExtensions": ["kotlin-implements"]
}
},
diff --git a/specs/reference-spec.json b/specs/reference-spec.json
index 5854234..dd00220 100644
--- a/specs/reference-spec.json
+++ b/specs/reference-spec.json
@@ -13,7 +13,8 @@
"x-entur-metadata": {
"id": "items",
"owner": "team-api",
- "audience": "partner"
+ "audience": "partner",
+ "devExtensions": ["x-kotlin-implements"]
}
},