rspec-openapi
rspec-openapi copied to clipboard
RFC: Update shared schemas in /components/schemas section
Summary
When rspec-openapi detects $ref
in the existing item to be modified, rspec-openapi update the referenced item in components
section.
Basic example
Let's say we have the openapi below, generated with rspec-openapi and modified manually to use $ref
.
"/tables":
get:
responses:
'200':
content:
application/json:
schema:
type: array
items:
"$ref": "#/components/schemas/Table"
example:
- (snip)
"/tables/{id}":
get:
parameters:
- name: id
in: path
required: true
schema:
type: integer
example: 1
responses:
'200':
content:
"$ref": "#/components/schemas/Table"
components:
schemas:
Table:
type: object
properties:
id:
type: integer
name:
type: string
If the implementation added a new field storage_size
, Table
in the #/components/schemas/
get updates.
Motivation
If there are "duplicated" schemas, such as Table
in get /tables
, post /tables
andget /tables/{id}
, some OpenAPI client generators generate separate types for each of duplicated schemas.
One example is openapi-typescript-codegen generating API client codes like below:
public static getTables( ..snip.. ): CancelablePromise<Array<{
id?: number;
name?: string;
description?: string;
database?: {
id?: number;
name?: string;
};
..snip..
}>> {..snip..}
public static postTables(..snip..): CancelablePromise<{
id?: number;
name?: string;
description?: string;
database?: {
id?: number;
name?: string;
};
..snip..
}> {..snip..}
public static getTables1(id: number): CancelablePromise<{
id?: number;
name?: string;
description?: string;
database?: {
id?: number;
name?: string;
};
..snip..
}> {..snip.. }
In this example, there are three unnamed structural types that represent Table
.
Those three types have the exact same type and are "compatible" if the type system at the client-side supports structural typing.
TypeScript does, but Java not.
There is another problem.
Since those types have no name, it is a bit tricky to refer the types in a nominal manner.
(One may use ReturnType<func>
and other utility types).
Users may reduce duplications by manually lifting the schemas into /components/schemas/Table
and using $refs
with it.
However, /components/schemas/Table
are not updated by rspec-openapi.
Users need to update /components/schemas/
by themselves, which diminishes the value of rspec-openapi somewhat.
If the schema in /components/schemas
gets updated automatically, it helps leverage OpenAPI files with client-generating tools with strong types.
Related issues
- https://github.com/k0kubun/rspec-openapi/issues/50
The feature looks good to me. While it's hard for rspec-openapi to generate $ref
by itself because of its design, when a human decides to carve out a $ref
manually, it makes total sense to let rspec-openapi update it. I still have no good idea to fully automate it, but it seems like a good first step towards better $ref
support.
It's a nitpick, but I guess this issue should be formatted like s/Summary/Proposal/
to make your point clear.