Add option to customize operationId in R client (#13000)

* add option to customize operationId in r client

* update doc
This commit is contained in:
William Cheng
2022-07-24 09:19:18 +08:00
committed by GitHub
parent 7c7ac2f0d3
commit 3ac88e95ed
4 changed files with 52 additions and 7 deletions

View File

@@ -9,3 +9,4 @@ additionalProperties:
useRlangExceptionHandling: true
returnExceptionOnFailure: true
errorObjectType: "ModelApiResponse"
operationIdNaming: PascalCase #default

View File

@@ -21,6 +21,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|errorObjectType|Error object type.| |null|
|exceptionPackage|Specify the exception handling package|<dl><dt>**default**</dt><dd>Use stop() for raising exceptions.</dd><dt>**rlang**</dt><dd>Use rlang package for exceptions.</dd></dl>|default|
|hideGenerationTimestamp|Hides the generation timestamp when files are generated.| |true|
|operationIdNaming|Naming convention for operationId (function name in the API)|<dl><dt>**PascalCase**</dt><dd>Pascal case (default)</dd><dt>**snake_case**</dt><dd>Snake case</dd><dt>**camelCase**</dt><dd>Camel case</dd></dl>|null|
|packageName|R package name (convention: lowercase).| |openapi|
|packageVersion|R package version.| |1.0.0|
|returnExceptionOnFailure|Throw an exception on non success response codes| |false|

View File

@@ -21,6 +21,7 @@ import com.samskivert.mustache.Mustache.Lambda;
import com.samskivert.mustache.Mustache;
import com.samskivert.mustache.Template;
import com.sun.media.sound.InvalidDataException;
import io.swagger.v3.oas.models.examples.Example;
import io.swagger.v3.oas.models.media.ArraySchema;
import io.swagger.v3.oas.models.media.Schema;
@@ -64,9 +65,13 @@ public class RClientCodegen extends DefaultCodegen implements CodegenConfig {
public static final String DEFAULT = "default";
public static final String RLANG = "rlang";
// naming convention for operationId (function names in the API)
public static final String OPERATIONID_NAMING = "operationIdNaming";
protected boolean useDefaultExceptionHandling = false;
protected boolean useRlangExceptionHandling = false;
protected String errorObjectType;
protected String operationIdNaming;
private Map<String, String> schemaKeyToModelNameCache = new HashMap<>();
@@ -177,6 +182,14 @@ public class RClientCodegen extends DefaultCodegen implements CodegenConfig {
cliOptions.add(new CliOption(CodegenConstants.EXCEPTION_ON_FAILURE, CodegenConstants.EXCEPTION_ON_FAILURE_DESC)
.defaultValue(Boolean.FALSE.toString()));
CliOption operationIdNaming = CliOption.newString(OPERATIONID_NAMING, "Naming convention for operationId (function name in the API)");
Map<String, String> operationIdNamingOptions = new HashMap<>();
operationIdNamingOptions.put("snake_case", "Snake case");
operationIdNamingOptions.put("camelCase", "Camel case");
operationIdNamingOptions.put("PascalCase", "Pascal case (default)");
operationIdNaming.setEnum(operationIdNamingOptions);
cliOptions.add(operationIdNaming);
exceptionPackages.put(DEFAULT, "Use stop() for raising exceptions.");
exceptionPackages.put(RLANG, "Use rlang package for exceptions.");
@@ -205,15 +218,14 @@ public class RClientCodegen extends DefaultCodegen implements CodegenConfig {
}
if (additionalProperties.containsKey(CodegenConstants.EXCEPTION_ON_FAILURE)) {
boolean booleanValue = Boolean.parseBoolean(additionalProperties.get(CodegenConstants.EXCEPTION_ON_FAILURE).toString());
setReturnExceptionOnFailure(booleanValue);
setReturnExceptionOnFailure(Boolean.parseBoolean(
additionalProperties.get(CodegenConstants.EXCEPTION_ON_FAILURE).toString()));
} else {
setReturnExceptionOnFailure(false);
}
if (additionalProperties.containsKey(EXCEPTION_PACKAGE)) {
String exceptionPackage = additionalProperties.get(EXCEPTION_PACKAGE).toString();
setExceptionPackageToUse(exceptionPackage);
setExceptionPackageToUse(additionalProperties.get(EXCEPTION_PACKAGE).toString());
} else {
setExceptionPackageToUse(DEFAULT);
}
@@ -223,6 +235,13 @@ public class RClientCodegen extends DefaultCodegen implements CodegenConfig {
}
additionalProperties.put(CodegenConstants.ERROR_OBJECT_TYPE, errorObjectType);
if (additionalProperties.containsKey(OPERATIONID_NAMING)) {
this.setOperationIdNaming(additionalProperties.get(OPERATIONID_NAMING).toString());
} else {
this.setOperationIdNaming("PascalCase"); // default to PascalCase for backward compatibility
}
additionalProperties.put(CodegenConstants.ERROR_OBJECT_TYPE, errorObjectType);
additionalProperties.put(CodegenConstants.PACKAGE_NAME, packageName);
additionalProperties.put(CodegenConstants.PACKAGE_VERSION, packageVersion);
additionalProperties.put(CodegenConstants.EXCEPTION_ON_FAILURE, returnExceptionOnFailure);
@@ -469,7 +488,16 @@ public class RClientCodegen extends DefaultCodegen implements CodegenConfig {
sanitizedOperationId = "call_" + sanitizedOperationId;
}
return camelize(sanitizedOperationId);
if ("PascalCase".equals(operationIdNaming)) {
return camelize(sanitizedOperationId);
} else if ("camelCase".equals(operationIdNaming)) {
return camelize(sanitizedOperationId, true);
} else if ("snake_case".equals(operationIdNaming)) {
return underscore(sanitizedOperationId);
} else {
LOGGER.error("Invalid operationIdNaming: {}. Please report the issue. Default to PascalCase for the time being", operationIdNaming);
return camelize(sanitizedOperationId);
}
}
@Override
@@ -542,6 +570,21 @@ public class RClientCodegen extends DefaultCodegen implements CodegenConfig {
this.errorObjectType = errorObjectType;
}
public void setOperationIdNaming(final String operationIdNaming) {
if (!("PascalCase".equals(operationIdNaming) || "camelCase".equals(operationIdNaming) ||
"snake_case".equals(operationIdNaming))) {
throw new IllegalArgumentException("Invalid operationIdNaming: " + operationIdNaming +
". Must be PascalCase, camelCase or snake_case");
}
if ("snake_case".equals(operationIdNaming)) {
additionalProperties.put("WithHttpInfo", "_with_http_info");
} else {
additionalProperties.put("WithHttpInfo", "WithHttpInfo");
}
this.operationIdNaming = operationIdNaming;
}
@Override
public String escapeQuotationMark(String input) {
// remove " to avoid code injection

View File

@@ -194,7 +194,7 @@
#' @return {{{returnType}}}{{^returnType}}void{{/returnType}}
#' @export
{{{operationId}}} = function({{#requiredParams}}{{paramName}}, {{/requiredParams}}{{#optionalParams}}{{paramName}} = {{^defaultValue}}NULL{{/defaultValue}}{{{defaultValue}}}, {{/optionalParams}}{{#vendorExtensions.x-streaming}}stream_callback = NULL, {{/vendorExtensions.x-streaming}}{{#returnType}}data_file = NULL, {{/returnType}}...) {
api_response <- self${{{operationId}}}WithHttpInfo({{#allParams}}{{paramName}}, {{/allParams}}{{#vendorExtensions.x-streaming}}stream_callback = stream_callback, {{/vendorExtensions.x-streaming}}{{#returnType}}data_file = data_file, {{/returnType}}...)
api_response <- self${{{operationId}}}{{WithHttpInfo}}({{#allParams}}{{paramName}}, {{/allParams}}{{#vendorExtensions.x-streaming}}stream_callback = stream_callback, {{/vendorExtensions.x-streaming}}{{#returnType}}data_file = data_file, {{/returnType}}...)
{{#vendorExtensions.x-streaming}}
if (typeof(stream_callback) == "closure") { # return void if streaming is enabled
return(invisible(NULL))
@@ -232,7 +232,7 @@
#' @param ... Other optional arguments
#' @return API response ({{{returnType}}}{{^returnType}}void{{/returnType}}) with additional information such as HTTP status code, headers
#' @export
{{{operationId}}}WithHttpInfo = function({{#requiredParams}}{{paramName}}, {{/requiredParams}}{{#optionalParams}}{{paramName}} = {{^defaultValue}}NULL{{/defaultValue}}{{{defaultValue}}}, {{/optionalParams}}{{#vendorExtensions.x-streaming}}stream_callback = NULL, {{/vendorExtensions.x-streaming}}{{#returnType}}data_file = NULL, {{/returnType}}...) {
{{{operationId}}}{{WithHttpInfo}} = function({{#requiredParams}}{{paramName}}, {{/requiredParams}}{{#optionalParams}}{{paramName}} = {{^defaultValue}}NULL{{/defaultValue}}{{{defaultValue}}}, {{/optionalParams}}{{#vendorExtensions.x-streaming}}stream_callback = NULL, {{/vendorExtensions.x-streaming}}{{#returnType}}data_file = NULL, {{/returnType}}...) {
args <- list(...)
query_params <- list()
header_params <- c()