christianhelle / refitter

A tool for generating Refit interfaces and contracts from OpenAPI specifications
https://refitter.github.io
MIT License
186 stars 40 forks source link

Code Generator adds numeric suffix to Interface method name when not needed #361

Open dammitjanet opened 5 months ago

dammitjanet commented 5 months ago

Describe the bug When the flag "multipleInterfaces" is set to "ByTag", the method names are still being renamed to have numerical suffixes even though the names are unique within the Interface (e.g. InfoGET3Async).

The check for method name uniqueness should be performed at the interface level, and not at the OpenAPI specification level.

    public partial interface IManageApi
    {
        [Headers("Accept: text/plain, application/json, text/json")]
        [Post("/api/manage/2fa")]
        Task<IApiResponse> _2faAsync([Body] TwoFactorRequest? body = default, CancellationToken cancellationToken = default);

        [Headers("Accept: text/plain, application/json, text/json")]
        [Get("/api/manage/info")]
        Task<IApiResponse> InfoGET3Async(CancellationToken cancellationToken = default);

        [Headers("Accept: text/plain, application/json, text/json")]
        [Post("/api/manage/info")]
        Task<IApiResponse> InfoPOSTAsync([Body] InfoRequest? body = default, [Header("confirmEmail")] string? confirmEmail = default, CancellationToken cancellationToken = default);
    }

Support Key: 7l7irxz

OpenAPI Specifications n/a

christianhelle commented 5 months ago

Thanks for taking the time to report this @dammitjanet

For the best code generation experience, I think that specifying the operationId at the OpenAPI specification level is best. Code generators, like mine, would try to do best guess attempts on how to name methods for each operation and one of the ways this is done is by looking at things like the verbs, path segments, and tags

You can maybe experiment with the --operation-name-generator CLI tool argument to try out different naming styles. Possible values for --operation-name-generator are documented here. The operation name generator options are taken directly from NSwag, the tool I use to parse the OpenAPI spec and generate models

dammitjanet commented 5 months ago

For the best code generation experience, I think that specifying the operationId at the OpenAPI specification level is best. Code generators, like mine, would try to do best guess attempts on how to name methods for each operation and one of the ways this is done is by looking at things like the verbs, path segments, and tags

That didn't work when I used

[SwaggerOperation(OperationId = "_2fa")]

but did when I used

[SwaggerOperation(OperationId = "TwoFactor")]

Even so, the generator should not create invalid method names, so I think its a bug, just one with a relatively easy workaround and is low priority.

christianhelle commented 5 months ago

We could look into implementing some sort of "last line of defense" that checks if the generated method name will compile and if not, make a naive attempt to replace invalid characters with "something else". Something like this would never be perfect but it could save someone like @dammitjanet time and avoid changing the OpenAPI spec itself to get the generated code to work