openapi-interfaces: Automatically generate GET, POST, PUT and JSON Merge Patch schemas for OpenAPI

EXPERIMENTAL. Details subject to change.

This tool extends OpenAPI 3.1.0 with the ability to generate related schemas automatically. Specifically, you can define a single interface type Widget, and automatically generate:

Installation

To install the latest version, first make sure you have a Rust toolchain. You can install one using these instructions. Then run:

sh cargo install -f openapi-interfaces

We will provide binaries at some point.

Usage

sh openapi-interfaces --help openapi-interfaces api_with_interfaces.yml -o api.yml

OpenAPI extensions

This tool defines a new components.interfaces section, which allows specifying "interface" types. For example:

```yaml components: # You can declare schemas normally if you wish. schemas: {}

# But we also support interface definitions. interfaces: Resource: emit: false # Do not include this in generated output. members: id: required: true schema: # Normal OpenAPI / JSON Schema definitions. type: string format: uuid Widget: # Include all fields from Resource. $includes: "Resource" members: # We can override properties from Resource using JSON # Merge Patch syntax. id: schema: example: e35a3c8d-5486-49ec-9b23-6747afc19570 name: required: true mutable: true schema: type: string comment: mutable: true schema: type: string readonly: required: true # This can't be updated once the object is created. mutable: false # But we do allow this to be set at creation time. # If omitted, initializable defaults to the value # of `mutable. initializable: true schema: type: string ```

This will automatically generate four Widget types:

yaml components: schemas: Widget: ... WidgetPost: ... WidgetPut: ... WidgetMergePatch: ...

For the complete definitions, see example_output.yml.

Referring to interfaces

We can then refer to interfaces using the new $interface key, with an appropriate variant:

yaml paths: /widgets: post: requestBody: required: true content: application/json: schema: # This becomes `$ref: "#/components/schemas/WidgetPost`. $interface: "Widget#Post" responses: 201: content: application/json: schema: # This becomes `$ref: "#/components/schemas/Widget`. $interface: "Widget"

Possible options are: