hey-api / openapi-ts

✨ Turn your OpenAPI specification into a beautiful TypeScript client

Home Page:https://heyapi.vercel.app

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Return types are not unique across services. They conflict.

ianberdin opened this issue · comments

Description

Hi, thanks again for your huge contribution to Open Source with this package.

It seems like we're doing something wrong because the type in JSDoc doesn't match the actual return type. As a result, the return type, like CreateResponse, is the same for all services.

We're trying to make an SDK that works like this using tags (users, carts, bookings) and operationIds (create):

api.users.create() -> UsersCreateResponse
api.carts.create() -> CartsCreateResponse
api.bookings.create() -> BookingsCreateResponse

But what we get is (always CreateResponse and CreateData):

/**
 * Create
 * No description
 * @param data The data for the request.
 * @param data.requestBody
 * @returns UsersCreateResponseDto Created
 * @throws ApiError
 */
public create(data: CreateData): CancelablePromise<CreateResponse> {
    return this.httpRequest.request({
        method: 'POST',
        url: '/api/v1/users/create',
        body: data.requestBody,
        mediaType: 'application/json',
    });
}

OpenAPI specification (optional)

"/api/v1/users/create": {
      "post": {
        "operationId": "create",
        "summary": "Create",
        "description": "Create an user",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UsersCreateRequestDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UsersCreateResponseDto"
                }
              }
            }
          },
        },
        "tags": [
          "Users"
        ]
      }
    },

"/api/v1/carts/create": {
      "post": {
        "operationId": "create",
        "summary": "Create",
        "description": "Create a cart",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CartsCreateRequestDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CartsCreateResponseDto"
                }
              }
            }
          },
        },
        "tags": [
          "Carts"
        ]
      }
    }

Configuration

@hey-api/openapi-ts \
        --input "${swagger_url}" \
        --output "${output_dir}" \
        --client fetch \
        --name "Api"

System information (optional)

No response

If we don't specify an operationId, the API will look like this:

api.users.usersControllerCreate() -> UsersControllerCreateResponse
api.carts.cartsControllerCreate() -> CartsControllerCreateResponse
api.bookings.bookingsControllerCreate() -> BookingsControllerCreateResponse
commented

Hey @ianberdin, is this a regression?

No, it's not. I can't use the next version 0.46.* because it breaks completely, so I'm using 0.45.3.

There is no this on root file, I see it does not use classes anymore (0.46.*):
image

Thank you for your quick response. The issue with this has been resolved.

The main problem now is non-unique names when using a custom operationId. Is there a way to fix this?

image

And this, if I set new hey-api fetch client:
image

commented

Not that I'm aware, will need to look at this. Thanks for reporting!

If I remove the operationId, it will look like this:

api.users.usersControllerCreate() - not very appealing for a customer-facing API :(

image
commented

Are you on Discord @ianberdin? Would like to understand your use case better

I've sent you a request in Discord.
@ianberdin mine username.

commented

I think you can resolve this with services.methodNameBuilder(), let me know if not