diff --git a/modules/openapi-generator/src/main/resources/r/NAMESPACE.mustache b/modules/openapi-generator/src/main/resources/r/NAMESPACE.mustache index b040f5adc44..720eb69bdab 100644 --- a/modules/openapi-generator/src/main/resources/r/NAMESPACE.mustache +++ b/modules/openapi-generator/src/main/resources/r/NAMESPACE.mustache @@ -5,6 +5,7 @@ import(R6) import(jsonlite) import(httr) import(base64enc) +import(stringr) # Core export(ApiClient) diff --git a/modules/openapi-generator/src/main/resources/r/api.mustache b/modules/openapi-generator/src/main/resources/r/api.mustache index 54fa845382e..cfcab5359b2 100644 --- a/modules/openapi-generator/src/main/resources/r/api.mustache +++ b/modules/openapi-generator/src/main/resources/r/api.mustache @@ -333,10 +333,18 @@ {{/isOAuth}} {{/authMethods}} + # The Accept request HTTP header + accepts = list({{#produces}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/produces}}) + + # The Content-Type representation header + content_types = list({{#consumes}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/consumes}}) + resp <- self$api_client$CallApi(url = paste0(self$api_client$base_path, url_path), method = "{{httpMethod}}", query_params = query_params, header_params = header_params, + accepts = accepts, + content_types = content_types, body = body, {{#vendorExtensions.x-streaming}} stream_callback = stream_callback, diff --git a/modules/openapi-generator/src/main/resources/r/api_client.mustache b/modules/openapi-generator/src/main/resources/r/api_client.mustache index a581d4af6b3..8e78e508898 100644 --- a/modules/openapi-generator/src/main/resources/r/api_client.mustache +++ b/modules/openapi-generator/src/main/resources/r/api_client.mustache @@ -133,14 +133,18 @@ ApiClient <- R6::R6Class( #' @param method HTTP method. #' @param query_params The query parameters. #' @param header_params The header parameters. + #' @param accepts The list of Accept headers. + #' @param content_types The list of Content-Type headers. #' @param body The HTTP request body. #' @param stream_callback Callback function to process the data stream #' @param ... Other optional arguments. #' @return HTTP response #' @export - CallApi = function(url, method, query_params, header_params, body, stream_callback = NULL, ...) { + CallApi = function(url, method, query_params, header_params, accepts, content_types, + body, stream_callback = NULL, ...) { - resp <- self$Execute(url, method, query_params, header_params, body, stream_callback = stream_callback, ...) + resp <- self$Execute(url, method, query_params, header_params, accepts, content_types, + body, stream_callback = stream_callback, ...) status_code <- httr::status_code(resp) if (is.null(self$max_retry_attempts)) { @@ -171,12 +175,15 @@ ApiClient <- R6::R6Class( #' @param method HTTP method. #' @param query_params The query parameters. #' @param header_params The header parameters. + #' @param accepts The list of Accept headers + #' @param content_types The list of Content-Type headers #' @param body The HTTP request body. #' @param stream_callback Callback function to process data stream #' @param ... Other optional arguments. #' @return HTTP response #' @export - Execute = function(url, method, query_params, header_params, body, stream_callback = NULL, ...) { + Execute = function(url, method, query_params, header_params, accepts, content_types, + body, stream_callback = NULL, ...) { headers <- httr::add_headers(c(header_params, self$default_headers)) {{! Adding timeout that can be set at the apiClient object level}} @@ -185,6 +192,18 @@ ApiClient <- R6::R6Class( http_timeout <- httr::timeout(self$timeout) } + # set HTTP accept header + accept = self$select_header(accepts) + if (!is.null(accept)) { + headers['Accept'] = accept + } + + # set HTTP content-type header + content_type = self$select_header(content_types) + if (!is.null(content_type)) { + headers['Content-Type'] = content_type + } + if (method == "GET") { if (typeof(stream_callback) == "closure") { httr::GET(url, query = query_params, headers, http_timeout, @@ -265,7 +284,6 @@ ApiClient <- R6::R6Class( resp_obj <- jsonlite::fromJSON(httr::content(resp, "text", encoding = "UTF-8")) self$deserializeObj(resp_obj, return_type, pkg_env) }, - #' Deserialize the response from jsonlite object based on the given type #' #' @description @@ -324,6 +342,31 @@ ApiClient <- R6::R6Class( return_obj <- obj } return_obj + }, + #' Return a propery header (for accept or content-type). If JSON-related MIME is found, + #' return it. Otherwise, return the first one, if any. + #' + #' @description + #' Return a propery header (for accept or content-type). If JSON-related MIME is found, + #' return it. Otherwise, return the first one, if any. + #' + #' @param headers A list of headers + #' @return A header (e.g. 'application/json') + #' @export + select_header = function(headers) { + if (length(headers) == 0) { + return(invisible(NULL)) + } else { + for (header in headers) { + if (str_detect(header, "(?i)^(application/json|[^;/ \t]+/[^;/ \t]+[+]json)[ \t]*(;.*)?$")) { + # return JSON-related MIME + return(header) + } + } + + # not json mime type, simply return the first one + return(headers[1]) + } } ) ) diff --git a/modules/openapi-generator/src/main/resources/r/description.mustache b/modules/openapi-generator/src/main/resources/r/description.mustache index 2a16f842bf1..7187fef5b5c 100644 --- a/modules/openapi-generator/src/main/resources/r/description.mustache +++ b/modules/openapi-generator/src/main/resources/r/description.mustache @@ -11,5 +11,5 @@ Encoding: UTF-8 License: {{#lambdaLicense}}{{licenseInfo}}{{/lambdaLicense}}{{^licenseInfo}}Unlicense{{/licenseInfo}} LazyData: true Suggests: testthat -Imports: jsonlite, httr, R6, base64enc +Imports: jsonlite, httr, R6, base64enc, stringr RoxygenNote: 7.2.0 diff --git a/samples/client/petstore/R/DESCRIPTION b/samples/client/petstore/R/DESCRIPTION index 2afb45624b0..d8e1a4dfcde 100644 --- a/samples/client/petstore/R/DESCRIPTION +++ b/samples/client/petstore/R/DESCRIPTION @@ -11,5 +11,5 @@ Encoding: UTF-8 License: Apache License 2.0 LazyData: true Suggests: testthat -Imports: jsonlite, httr, R6, base64enc +Imports: jsonlite, httr, R6, base64enc, stringr RoxygenNote: 7.2.0 diff --git a/samples/client/petstore/R/NAMESPACE b/samples/client/petstore/R/NAMESPACE index d8fc867efa7..667ff45b7bf 100644 --- a/samples/client/petstore/R/NAMESPACE +++ b/samples/client/petstore/R/NAMESPACE @@ -5,6 +5,7 @@ import(R6) import(jsonlite) import(httr) import(base64enc) +import(stringr) # Core export(ApiClient) diff --git a/samples/client/petstore/R/R/api_client.R b/samples/client/petstore/R/R/api_client.R index ae2cd498a9c..77ed87bd912 100644 --- a/samples/client/petstore/R/R/api_client.R +++ b/samples/client/petstore/R/R/api_client.R @@ -138,14 +138,18 @@ ApiClient <- R6::R6Class( #' @param method HTTP method. #' @param query_params The query parameters. #' @param header_params The header parameters. + #' @param accepts The list of Accept headers. + #' @param content_types The list of Content-Type headers. #' @param body The HTTP request body. #' @param stream_callback Callback function to process the data stream #' @param ... Other optional arguments. #' @return HTTP response #' @export - CallApi = function(url, method, query_params, header_params, body, stream_callback = NULL, ...) { + CallApi = function(url, method, query_params, header_params, accepts, content_types, + body, stream_callback = NULL, ...) { - resp <- self$Execute(url, method, query_params, header_params, body, stream_callback = stream_callback, ...) + resp <- self$Execute(url, method, query_params, header_params, accepts, content_types, + body, stream_callback = stream_callback, ...) status_code <- httr::status_code(resp) if (is.null(self$max_retry_attempts)) { @@ -176,12 +180,15 @@ ApiClient <- R6::R6Class( #' @param method HTTP method. #' @param query_params The query parameters. #' @param header_params The header parameters. + #' @param accepts The list of Accept headers + #' @param content_types The list of Content-Type headers #' @param body The HTTP request body. #' @param stream_callback Callback function to process data stream #' @param ... Other optional arguments. #' @return HTTP response #' @export - Execute = function(url, method, query_params, header_params, body, stream_callback = NULL, ...) { + Execute = function(url, method, query_params, header_params, accepts, content_types, + body, stream_callback = NULL, ...) { headers <- httr::add_headers(c(header_params, self$default_headers)) http_timeout <- NULL @@ -189,6 +196,18 @@ ApiClient <- R6::R6Class( http_timeout <- httr::timeout(self$timeout) } + # set HTTP accept header + accept = self$select_header(accepts) + if (!is.null(accept)) { + headers['Accept'] = accept + } + + # set HTTP content-type header + content_type = self$select_header(content_types) + if (!is.null(content_type)) { + headers['Content-Type'] = content_type + } + if (method == "GET") { if (typeof(stream_callback) == "closure") { httr::GET(url, query = query_params, headers, http_timeout, @@ -264,7 +283,6 @@ ApiClient <- R6::R6Class( resp_obj <- jsonlite::fromJSON(httr::content(resp, "text", encoding = "UTF-8")) self$deserializeObj(resp_obj, return_type, pkg_env) }, - #' Deserialize the response from jsonlite object based on the given type #' #' @description @@ -323,6 +341,31 @@ ApiClient <- R6::R6Class( return_obj <- obj } return_obj + }, + #' Return a propery header (for accept or content-type). If JSON-related MIME is found, + #' return it. Otherwise, return the first one, if any. + #' + #' @description + #' Return a propery header (for accept or content-type). If JSON-related MIME is found, + #' return it. Otherwise, return the first one, if any. + #' + #' @param headers A list of headers + #' @return A header (e.g. 'application/json') + #' @export + select_header = function(headers) { + if (length(headers) == 0) { + return(invisible(NULL)) + } else { + for (header in headers) { + if (str_detect(header, "(?i)^(application/json|[^;/ \t]+/[^;/ \t]+[+]json)[ \t]*(;.*)?$")) { + # return JSON-related MIME + return(header) + } + } + + # not json mime type, simply return the first one + return(headers[1]) + } } ) ) diff --git a/samples/client/petstore/R/R/fake_api.R b/samples/client/petstore/R/R/fake_api.R index 250b0a822d4..fe1ae74cf00 100644 --- a/samples/client/petstore/R/R/fake_api.R +++ b/samples/client/petstore/R/R/fake_api.R @@ -137,10 +137,18 @@ FakeApi <- R6::R6Class( body <- NULL url_path <- "/fake/data_file" + # The Accept request HTTP header + accepts = list("application/xml", "application/json") + + # The Content-Type representation header + content_types = list() + resp <- self$api_client$CallApi(url = paste0(self$api_client$base_path, url_path), method = "GET", query_params = query_params, header_params = header_params, + accepts = accepts, + content_types = content_types, body = body, ...) diff --git a/samples/client/petstore/R/R/pet_api.R b/samples/client/petstore/R/R/pet_api.R index 707283312ac..fa60b70ad2d 100644 --- a/samples/client/petstore/R/R/pet_api.R +++ b/samples/client/petstore/R/R/pet_api.R @@ -588,10 +588,18 @@ PetApi <- R6::R6Class( # HTTP basic auth header_params["Authorization"] <- paste("Basic", base64enc::base64encode(charToRaw(paste(self$api_client$username, self$api_client$password, sep = ":")))) + # The Accept request HTTP header + accepts = list("application/xml", "application/json") + + # The Content-Type representation header + content_types = list("application/json", "application/xml", "multipart/related") + resp <- self$api_client$CallApi(url = paste0(self$api_client$base_path, url_path), method = "POST", query_params = query_params, header_params = header_params, + accepts = accepts, + content_types = content_types, body = body, ...) @@ -690,10 +698,18 @@ PetApi <- R6::R6Class( # OAuth token header_params["Authorization"] <- paste("Bearer", self$api_client$access_token, sep = " ") + # The Accept request HTTP header + accepts = list() + + # The Content-Type representation header + content_types = list() + resp <- self$api_client$CallApi(url = paste0(self$api_client$base_path, url_path), method = "DELETE", query_params = query_params, header_params = header_params, + accepts = accepts, + content_types = content_types, body = body, ...) @@ -775,10 +791,18 @@ PetApi <- R6::R6Class( # OAuth token header_params["Authorization"] <- paste("Bearer", self$api_client$access_token, sep = " ") + # The Accept request HTTP header + accepts = list("application/xml", "application/json") + + # The Content-Type representation header + content_types = list() + resp <- self$api_client$CallApi(url = paste0(self$api_client$base_path, url_path), method = "GET", query_params = query_params, header_params = header_params, + accepts = accepts, + content_types = content_types, body = body, ...) @@ -873,10 +897,18 @@ PetApi <- R6::R6Class( # OAuth token header_params["Authorization"] <- paste("Bearer", self$api_client$access_token, sep = " ") + # The Accept request HTTP header + accepts = list("application/xml", "application/json") + + # The Content-Type representation header + content_types = list() + resp <- self$api_client$CallApi(url = paste0(self$api_client$base_path, url_path), method = "GET", query_params = query_params, header_params = header_params, + accepts = accepts, + content_types = content_types, body = body, ...) @@ -974,10 +1006,18 @@ PetApi <- R6::R6Class( header_params["Authorization"] <- paste("Bearer", self$api_client$bearer_token, sep = " ") + # The Accept request HTTP header + accepts = list("application/xml", "application/json") + + # The Content-Type representation header + content_types = list() + resp <- self$api_client$CallApi(url = paste0(self$api_client$base_path, url_path), method = "GET", query_params = query_params, header_params = header_params, + accepts = accepts, + content_types = content_types, body = body, ...) @@ -1084,10 +1124,18 @@ PetApi <- R6::R6Class( header_params["api_key"] <- paste(unlist(self$api_client$api_keys["api_key"]), collapse = "") } + # The Accept request HTTP header + accepts = list("application/xml", "application/json") + + # The Content-Type representation header + content_types = list() + resp <- self$api_client$CallApi(url = paste0(self$api_client$base_path, url_path), method = "GET", query_params = query_params, header_params = header_params, + accepts = accepts, + content_types = content_types, body = body, stream_callback = stream_callback, ...) @@ -1192,10 +1240,18 @@ PetApi <- R6::R6Class( # OAuth token header_params["Authorization"] <- paste("Bearer", self$api_client$access_token, sep = " ") + # The Accept request HTTP header + accepts = list("application/xml", "application/json") + + # The Content-Type representation header + content_types = list("application/json", "application/xml", "multipart/related") + resp <- self$api_client$CallApi(url = paste0(self$api_client$base_path, url_path), method = "PUT", query_params = query_params, header_params = header_params, + accepts = accepts, + content_types = content_types, body = body, ...) @@ -1300,10 +1356,18 @@ PetApi <- R6::R6Class( # OAuth token header_params["Authorization"] <- paste("Bearer", self$api_client$access_token, sep = " ") + # The Accept request HTTP header + accepts = list() + + # The Content-Type representation header + content_types = list("application/x-www-form-urlencoded") + resp <- self$api_client$CallApi(url = paste0(self$api_client$base_path, url_path), method = "POST", query_params = query_params, header_params = header_params, + accepts = accepts, + content_types = content_types, body = body, ...) @@ -1397,10 +1461,18 @@ PetApi <- R6::R6Class( # OAuth token header_params["Authorization"] <- paste("Bearer", self$api_client$access_token, sep = " ") + # The Accept request HTTP header + accepts = list("application/json") + + # The Content-Type representation header + content_types = list("multipart/form-data") + resp <- self$api_client$CallApi(url = paste0(self$api_client$base_path, url_path), method = "POST", query_params = query_params, header_params = header_params, + accepts = accepts, + content_types = content_types, body = body, ...) diff --git a/samples/client/petstore/R/R/store_api.R b/samples/client/petstore/R/R/store_api.R index 9ce83ad4e4f..41c63c796a7 100644 --- a/samples/client/petstore/R/R/store_api.R +++ b/samples/client/petstore/R/R/store_api.R @@ -289,10 +289,18 @@ StoreApi <- R6::R6Class( } + # The Accept request HTTP header + accepts = list() + + # The Content-Type representation header + content_types = list() + resp <- self$api_client$CallApi(url = paste0(self$api_client$base_path, url_path), method = "DELETE", query_params = query_params, header_params = header_params, + accepts = accepts, + content_types = content_types, body = body, ...) @@ -367,10 +375,18 @@ StoreApi <- R6::R6Class( header_params["api_key"] <- paste(unlist(self$api_client$api_keys["api_key"]), collapse = "") } + # The Accept request HTTP header + accepts = list("application/json") + + # The Content-Type representation header + content_types = list() + resp <- self$api_client$CallApi(url = paste0(self$api_client$base_path, url_path), method = "GET", query_params = query_params, header_params = header_params, + accepts = accepts, + content_types = content_types, body = body, ...) @@ -467,10 +483,18 @@ StoreApi <- R6::R6Class( } + # The Accept request HTTP header + accepts = list("application/xml", "application/json") + + # The Content-Type representation header + content_types = list() + resp <- self$api_client$CallApi(url = paste0(self$api_client$base_path, url_path), method = "GET", query_params = query_params, header_params = header_params, + accepts = accepts, + content_types = content_types, body = body, ...) @@ -568,10 +592,18 @@ StoreApi <- R6::R6Class( url_path <- "/store/order" + # The Accept request HTTP header + accepts = list("application/xml", "application/json") + + # The Content-Type representation header + content_types = list("application/json") + resp <- self$api_client$CallApi(url = paste0(self$api_client$base_path, url_path), method = "POST", query_params = query_params, header_params = header_params, + accepts = accepts, + content_types = content_types, body = body, ...) diff --git a/samples/client/petstore/R/R/user_api.R b/samples/client/petstore/R/R/user_api.R index 07dbd47a307..8c0bc7080ff 100644 --- a/samples/client/petstore/R/R/user_api.R +++ b/samples/client/petstore/R/R/user_api.R @@ -480,10 +480,18 @@ UserApi <- R6::R6Class( header_params["api_key"] <- paste(unlist(self$api_client$api_keys["api_key"]), collapse = "") } + # The Accept request HTTP header + accepts = list() + + # The Content-Type representation header + content_types = list("application/json") + resp <- self$api_client$CallApi(url = paste0(self$api_client$base_path, url_path), method = "POST", query_params = query_params, header_params = header_params, + accepts = accepts, + content_types = content_types, body = body, ...) @@ -573,10 +581,18 @@ UserApi <- R6::R6Class( header_params["api_key"] <- paste(unlist(self$api_client$api_keys["api_key"]), collapse = "") } + # The Accept request HTTP header + accepts = list() + + # The Content-Type representation header + content_types = list("application/json") + resp <- self$api_client$CallApi(url = paste0(self$api_client$base_path, url_path), method = "POST", query_params = query_params, header_params = header_params, + accepts = accepts, + content_types = content_types, body = body, ...) @@ -666,10 +682,18 @@ UserApi <- R6::R6Class( header_params["api_key"] <- paste(unlist(self$api_client$api_keys["api_key"]), collapse = "") } + # The Accept request HTTP header + accepts = list() + + # The Content-Type representation header + content_types = list("application/json") + resp <- self$api_client$CallApi(url = paste0(self$api_client$base_path, url_path), method = "POST", query_params = query_params, header_params = header_params, + accepts = accepts, + content_types = content_types, body = body, ...) @@ -755,10 +779,18 @@ UserApi <- R6::R6Class( header_params["api_key"] <- paste(unlist(self$api_client$api_keys["api_key"]), collapse = "") } + # The Accept request HTTP header + accepts = list() + + # The Content-Type representation header + content_types = list() + resp <- self$api_client$CallApi(url = paste0(self$api_client$base_path, url_path), method = "DELETE", query_params = query_params, header_params = header_params, + accepts = accepts, + content_types = content_types, body = body, ...) @@ -842,10 +874,18 @@ UserApi <- R6::R6Class( } + # The Accept request HTTP header + accepts = list("application/xml", "application/json") + + # The Content-Type representation header + content_types = list() + resp <- self$api_client$CallApi(url = paste0(self$api_client$base_path, url_path), method = "GET", query_params = query_params, header_params = header_params, + accepts = accepts, + content_types = content_types, body = body, ...) @@ -947,10 +987,18 @@ UserApi <- R6::R6Class( body <- NULL url_path <- "/user/login" + # The Accept request HTTP header + accepts = list("application/xml", "application/json") + + # The Content-Type representation header + content_types = list() + resp <- self$api_client$CallApi(url = paste0(self$api_client$base_path, url_path), method = "GET", query_params = query_params, header_params = header_params, + accepts = accepts, + content_types = content_types, body = body, ...) @@ -1036,10 +1084,18 @@ UserApi <- R6::R6Class( header_params["api_key"] <- paste(unlist(self$api_client$api_keys["api_key"]), collapse = "") } + # The Accept request HTTP header + accepts = list() + + # The Content-Type representation header + content_types = list() + resp <- self$api_client$CallApi(url = paste0(self$api_client$base_path, url_path), method = "GET", query_params = query_params, header_params = header_params, + accepts = accepts, + content_types = content_types, body = body, ...) @@ -1139,10 +1195,18 @@ UserApi <- R6::R6Class( header_params["api_key"] <- paste(unlist(self$api_client$api_keys["api_key"]), collapse = "") } + # The Accept request HTTP header + accepts = list() + + # The Content-Type representation header + content_types = list("application/json") + resp <- self$api_client$CallApi(url = paste0(self$api_client$base_path, url_path), method = "PUT", query_params = query_params, header_params = header_params, + accepts = accepts, + content_types = content_types, body = body, ...) diff --git a/samples/client/petstore/R/build_and_test.bash b/samples/client/petstore/R/build_and_test.bash index 2079f75da03..0e7828ec879 100644 --- a/samples/client/petstore/R/build_and_test.bash +++ b/samples/client/petstore/R/build_and_test.bash @@ -18,6 +18,7 @@ Rscript -e "install.packages('base64enc', repos='$REPO', lib='$R_LIBS_USER')" Rscript -e "install.packages('rlang', repos='$REPO', lib='$R_LIBS_USER')" Rscript -e "install.packages('rjson', repos='$REPO', lib='$R_LIBS_USER')" Rscript -e "install.packages('devtools', repos='$REPO', lib='$R_LIBS_USER')" +Rscript -e "install.packages('stringr', repos='$REPO', lib='$R_LIBS_USER')" rm petstore_1.0.0.tar.gz || true