swagger-api / swagger-codegen

swagger-codegen contains a template-driven engine to generate documentation, API clients and server stubs in different languages by parsing your OpenAPI / Swagger definition.
http://swagger.io
Apache License 2.0
16.94k stars 6.03k forks source link

[swift5] Entire path and HTTP method in operation signature #10452

Open ghost opened 4 years ago

ghost commented 4 years ago
Description

We've been using swagger-codegen 2 and now we're moving over to swagger-codegen 3 as we're preparing to use OpenAPI 3. When trying it out it seems that the entire path of each endpoint is added as a prefix to each operation along with the HTTP method as a suffix.

Before:

open class func copy(fileId: String) -> Observable<CopyFileCommandResponse>

After:

open class func apiV1FileFileIdCopyPost(fileId: String) -> Observable<CopyFileCommandResponse>

I've tried to find the reason for this by reading the documentation and the source code as I'm not sure how to use it. But it is hard to find any documentation describing this feature and that is why I've created this issue.

Swagger-codegen version

2.4.15 (99ed191d0a71daf8613d15371e381c649e325479) 3.0.22-SNAPSHOT (ad1b8bb54ce5eb1677426b5a49e80102590badc1)

Swagger declaration file content or url

2.0: https://gist.github.com/hlineholm-flir/a36f61d1d84a143d461b4cbb3772c181 3.0.1: https://gist.github.com/hlineholm-flir/bb390db34cd07742ca1d739481f2656b

Command line used for generation

swagger-codegen-cli.jar generate -l swift5 -I ./swagger.json -o ./generated-api

Suggest a fix/enhancement
ghost commented 4 years ago

I made a change to our fork of swagger-codegen-generators where I've overridden the generation of the operationId.

Swift5Codegen.java

@Override
protected String getOrGenerateOperationId(Operation operation, String path, String httpMethod) {
    String operationId = operation.getOperationId();
    if (StringUtils.isBlank(operationId)) {
        String tmpPath = path;
        tmpPath = tmpPath.replaceAll("\\/api\\/v[0-9]{1,}", "");
        tmpPath = tmpPath.replaceAll("\\/\\{.*\\}", "");
        tmpPath = tmpPath.replaceAll("\\/", "_");
        tmpPath = camelize(tmpPath);
        tmpPath = StringUtils.lowerCase(httpMethod) + tmpPath;
        operationId = sanitizeName(tmpPath);
        LOGGER.warn("Empty operationId found for path: " + httpMethod + " " + path + ". Renamed to auto-generated operationId: " + operationId);
    }
    return operationId;
}

DefaultCodegenConfig.java

/**
 * Get operationId from the operation object, and if it's blank, generate a new one from the given parameters.
 *
 * @param operation the operation object
 * @param path the path of the operation
 * @param httpMethod the HTTP method of the operation
 * @return the (generated) operationId
 */
protected String getOrGenerateOperationId(Operation operation, String path, String httpMethod) {
    String operationId = operation.getOperationId();
    if (StringUtils.isBlank(operationId)) {
        String tmpPath = path;
        tmpPath = tmpPath.replaceAll("\\{", "");
        tmpPath = tmpPath.replaceAll("\\}", "");
        String[] parts = (tmpPath + "/" + httpMethod).split("/");
        StringBuilder builder = new StringBuilder();
        if ("/".equals(tmpPath)) {
            // must be root tmpPath
            builder.append("root");
        }
        for (String part : parts) {
            if (part.length() > 0) {
                if (builder.toString().length() == 0) {
                    part = Character.toLowerCase(part.charAt(0)) + part.substring(1);
                } else {
                    part = initialCaps(part);
                }
                builder.append(part);
            }
        }
        operationId = sanitizeName(builder.toString());
        LOGGER.warn("Empty operationId found for path: " + httpMethod + " " + path + ". Renamed to auto-generated operationId: " + operationId);
    }
    return operationId;
}