Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: Update shared schemas in /components/schemas section #65

Closed
exoego opened this issue Jul 29, 2022 · 1 comment · Fixed by #67
Closed

RFC: Update shared schemas in /components/schemas section #65

exoego opened this issue Jul 29, 2022 · 1 comment · Fixed by #67
Labels
enhancement New feature or request

Comments

@exoego
Copy link
Owner

exoego commented Jul 29, 2022

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

@exoego exoego changed the title _ RFC: Update components/schemas Jul 29, 2022
@exoego exoego added the enhancement New feature or request label Jul 29, 2022
@exoego exoego changed the title RFC: Update components/schemas RFC: Update shared schemas in /components/schemas section Jul 29, 2022
@k0kubun
Copy link
Collaborator

k0kubun commented Jul 29, 2022

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.

@exoego exoego mentioned this issue Aug 9, 2022
2 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants