Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ BOAT is still under development and subject to change.

See also: https://github.com/Backbase/backbase-openapi-tools/releases


## 0.18.6
* * Java RestTemplate generator: added `useSingleRequestParameter` support to replace positional parameter lists with named `*Param` objects for multi-parameter operations,
see [boat-maven-plugin README](boat-maven-plugin/README.md#single-request-parameter).

## 0.18.4
* **Breaking change**: `boat:bundle` and `boat:generate` (when `bundleSpecs` is enabled) now de-duplicate
`components/schemas` entries that are structurally identical but were registered under different names
Expand Down
13 changes: 13 additions & 0 deletions boat-maven-plugin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,19 @@ Same with `generate` but with opinionated defaults for Rest Template Client
</additionalProperties>
</configuration>

### Single request parameter

When enabled, BOAT generates a `*Param` inner class for multi-parameter API operations and uses it as
the method's single argument instead of a positional parameter list. Operations with zero or one parameter
remain unchanged.

<configuration>
...
<configOptions>
<useSingleRequestParameter>true</useSingleRequestParameter>
</configOptions>
</configuration>

### Property & Enum Name Mappings (new)

Two new optional parameters are supported by the BOAT plugin (mirroring OpenAPI Generator capabilities) to rename generated members without post-processing:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,111 +52,26 @@ public class {{classname}} extends BaseApi {
}

{{#operation}}
/**
* {{summary}}
* {{notes}}
{{#responses}}
* <p><b>{{code}}</b>{{#message}} - {{.}}{{/message}}
{{/responses}}
{{#allParams}}
* @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}
{{/allParams}}
{{#returnType}}
* @return {{.}}
{{/returnType}}
* @throws RestClientException if an error occurs while attempting to invoke the API
{{#externalDocs}}
* {{description}}
* @see <a href="{{url}}">{{summary}} Documentation</a>
{{/externalDocs}}
{{#isDeprecated}}
* @deprecated
{{/isDeprecated}}
*/
{{#isDeprecated}}
@Deprecated
{{/isDeprecated}}
public {{#returnType}}{{#isResponseFile}}{{#useAbstractionForFiles}}org.springframework.core.io.Resource{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{{.}}}{{/useAbstractionForFiles}}{{/isResponseFile}}{{^isResponseFile}}{{{.}}}{{/isResponseFile}} {{/returnType}}{{^returnType}}void {{/returnType}}{{operationId}}({{#allParams}}{{#isFile}}{{#useAbstractionForFiles}}{{#collectionFormat}}java.util.Collection<org.springframework.core.io.Resource>{{/collectionFormat}}{{^collectionFormat}}org.springframework.core.io.Resource{{/collectionFormat}}{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{{dataType}}}{{/useAbstractionForFiles}}{{/isFile}}{{^isFile}}{{{dataType}}}{{/isFile}} {{paramName}}{{^-last}}, {{/-last}}{{/allParams}}) throws RestClientException {
{{#returnType}}
return {{operationId}}WithHttpInfo({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}}).getBody();
{{/returnType}}
{{^returnType}}
{{operationId}}WithHttpInfo({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}});
{{/returnType}}
}

/**
* {{summary}}
* {{notes}}
{{#responses}}
* <p><b>{{code}}</b>{{#message}} - {{.}}{{/message}}
{{/responses}}
{{#allParams}}
* @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}
{{/allParams}}
* @return ResponseEntity&lt;{{returnType}}{{^returnType}}Void{{/returnType}}&gt;
* @throws RestClientException if an error occurs while attempting to invoke the API
{{#externalDocs}}
* {{description}}
* @see <a href="{{url}}">{{summary}} Documentation</a>
{{/externalDocs}}
{{#isDeprecated}}
* @deprecated
{{/isDeprecated}}
*/
{{#isDeprecated}}
@Deprecated
{{/isDeprecated}}
public ResponseEntity<{{#returnType}}{{#isResponseFile}}{{#useAbstractionForFiles}}org.springframework.core.io.Resource{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{{.}}}{{/useAbstractionForFiles}}{{/isResponseFile}}{{^isResponseFile}}{{{.}}}{{/isResponseFile}}{{/returnType}}{{^returnType}}Void{{/returnType}}> {{operationId}}WithHttpInfo({{#allParams}}{{#isFile}}{{#useAbstractionForFiles}}{{#collectionFormat}}java.util.Collection<org.springframework.core.io.Resource>{{/collectionFormat}}{{^collectionFormat}}org.springframework.core.io.Resource{{/collectionFormat}}{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{{dataType}}}{{/useAbstractionForFiles}}{{/isFile}}{{^isFile}}{{{dataType}}}{{/isFile}} {{paramName}}{{^-last}}, {{/-last}}{{/allParams}}) throws RestClientException {
Object localVarPostBody = {{#bodyParam}}{{paramName}}{{/bodyParam}}{{^bodyParam}}null{{/bodyParam}};
{{#allParams}}{{#required}}
// verify the required parameter '{{paramName}}' is set
if ({{paramName}} == null) {
throw new HttpClientErrorException(HttpStatus.BAD_REQUEST, "Missing the required parameter '{{paramName}}' when calling {{operationId}}");
}
{{/required}}{{/allParams}}{{#hasPathParams}}
// create path and map variables
final Map<String, Object> uriVariables = new HashMap<String, Object>();{{#pathParams}}
uriVariables.put("{{baseName}}", {{#collectionFormat}}apiClient.collectionPathParameterToString(ApiClient.CollectionFormat.valueOf("{{{collectionFormat}}}".toUpperCase()), {{{paramName}}}){{/collectionFormat}}{{^collectionFormat}}{{{paramName}}}{{/collectionFormat}});{{/pathParams}}{{/hasPathParams}}

final MultiValueMap<String, String> localVarQueryParams = new LinkedMultiValueMap<String, String>();
final HttpHeaders localVarHeaderParams = new HttpHeaders();
final MultiValueMap<String, String> localVarCookieParams = new LinkedMultiValueMap<String, String>();
final MultiValueMap<String, Object> localVarFormParams = new LinkedMultiValueMap<String, Object>();{{#hasQueryParams}}

{{#queryParams}}{{#isExplode}}{{#hasVars}}
if ({{paramName}} != null) {
{{#vars}} localVarQueryParams.putAll(apiClient.parameterToMultiValueMap({{#collectionFormat}}ApiClient.CollectionFormat.valueOf("{{{.}}}".toUpperCase(Locale.ROOT)){{/collectionFormat}}{{^collectionFormat}}null{{/collectionFormat}}, "{{baseName}}", {{paramName}}.{{getter}}()));
{{/vars}}}{{/hasVars}}{{^hasVars}}localVarQueryParams.putAll(apiClient.parameterToMultiValueMap({{#collectionFormat}}ApiClient.CollectionFormat.valueOf("{{{.}}}".toUpperCase(Locale.ROOT)){{/collectionFormat}}{{^collectionFormat}}null{{/collectionFormat}}, "{{baseName}}", {{paramName}}));
{{/hasVars}}{{/isExplode}}{{^isExplode}}localVarQueryParams.putAll(apiClient.parameterToMultiValueMap({{#collectionFormat}}ApiClient.CollectionFormat.valueOf("{{{.}}}".toUpperCase(Locale.ROOT)){{/collectionFormat}}{{^collectionFormat}}null{{/collectionFormat}}, "{{baseName}}", {{paramName}}));
{{/isExplode}}{{/queryParams}}{{/hasQueryParams}}{{#hasHeaderParams}}

{{#headerParams}}if ({{paramName}} != null)
localVarHeaderParams.add("{{baseName}}", apiClient.parameterToString({{paramName}}));{{^-last}}
{{/-last}}{{/headerParams}}{{/hasHeaderParams}}{{#hasCookieParams}}

{{#cookieParams}}if ({{paramName}} != null)
localVarCookieParams.add("{{baseName}}", apiClient.parameterToString({{paramName}}));{{^-last}}
{{/-last}}{{/cookieParams}}{{/hasCookieParams}}{{#hasFormParams}}

{{#formParams}}if ({{paramName}} != null)
localVarFormParams.{{^collectionFormat}}add{{/collectionFormat}}{{#collectionFormat}}addAll{{/collectionFormat}}("{{baseName}}", {{#isFile}}{{^collectionFormat}}{{#useAbstractionForFiles}}{{paramName}}{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}new FileSystemResource({{paramName}}){{/useAbstractionForFiles}}{{/collectionFormat}}{{/isFile}}{{#isFile}}{{#collectionFormat}}{{paramName}}.stream(){{^useAbstractionForFiles}}.map(FileSystemResource::new){{/useAbstractionForFiles}}.collect(Collectors.toList()){{/collectionFormat}}{{/isFile}}{{^isFile}}{{paramName}}{{/isFile}});{{^-last}}
{{/-last}}{{/formParams}}{{/hasFormParams}}

final String[] localVarAccepts = { {{#hasProduces}}
{{#produces}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/produces}}
{{/hasProduces}} };
final List<MediaType> localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
final String[] localVarContentTypes = { {{#hasConsumes}}
{{#consumes}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/consumes}}
{{/hasConsumes}} };
final MediaType localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
{{! Keep positional methods for zero- and one-parameter operations.
For multi-parameter operations, use *Param when singleRequestParameter is enabled. }}
{{^singleRequestParameter}}
{{>libraries/resttemplate/positionalMethods}}
{{/singleRequestParameter}}
{{#singleRequestParameter}}
{{^hasParams}}
{{>libraries/resttemplate/positionalMethods}}
{{/hasParams}}
{{#hasSingleParam}}
{{>libraries/resttemplate/positionalMethods}}
{{/hasSingleParam}}
{{! Param-object methods: 2+ params when singleRequestParameter=true }}
{{#hasParams}}
{{^hasSingleParam}}
{{>libraries/resttemplate/singleRequestParameter}}
{{/hasSingleParam}}
{{/hasParams}}
{{/singleRequestParameter}}

String[] localVarAuthNames = new String[] { {{#authMethods}}"{{name}}"{{^-last}}, {{/-last}}{{/authMethods}} };

{{#returnType}}ParameterizedTypeReference<{{#returnType}}{{#isResponseFile}}{{#useAbstractionForFiles}}org.springframework.core.io.Resource{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{{.}}}{{/useAbstractionForFiles}}{{/isResponseFile}}{{^isResponseFile}}{{{.}}}{{/isResponseFile}}{{/returnType}}> localReturnType = new ParameterizedTypeReference<{{#returnType}}{{#isResponseFile}}{{#useAbstractionForFiles}}org.springframework.core.io.Resource{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{{.}}}{{/useAbstractionForFiles}}{{/isResponseFile}}{{^isResponseFile}}{{{.}}}{{/isResponseFile}}{{/returnType}}>() {};{{/returnType}}{{^returnType}}ParameterizedTypeReference<Void> localReturnType = new ParameterizedTypeReference<Void>() {};{{/returnType}}
return apiClient.invokeAPI("{{{path}}}", HttpMethod.{{httpMethod}}, {{#hasPathParams}}uriVariables{{/hasPathParams}}{{^hasPathParams}}Collections.<String, Object>emptyMap(){{/hasPathParams}}, localVarQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAccept, localVarContentType, localVarAuthNames, localReturnType);
}
{{#-last}}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/**
* Parameters for the {@link #{{operationId}}({{#lambda.titlecase}}{{operationId}}{{/lambda.titlecase}}Param)}
* operation.
*/
public static class {{#lambda.titlecase}}{{operationId}}{{/lambda.titlecase}}Param {
{{#allParams}}
private {{#isFile}}{{#useAbstractionForFiles}}{{#collectionFormat}}java.util.Collection<org.springframework.core.io.Resource>{{/collectionFormat}}{{^collectionFormat}}org.springframework.core.io.Resource{{/collectionFormat}}{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{{dataType}}}{{/useAbstractionForFiles}}{{/isFile}}{{^isFile}}{{{dataType}}}{{/isFile}} {{paramName}};
{{/allParams}}

public {{#lambda.titlecase}}{{operationId}}{{/lambda.titlecase}}Param() {
}

{{#allParams}}
public {{#isFile}}{{#useAbstractionForFiles}}{{#collectionFormat}}java.util.Collection<org.springframework.core.io.Resource>{{/collectionFormat}}{{^collectionFormat}}org.springframework.core.io.Resource{{/collectionFormat}}{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{{dataType}}}{{/useAbstractionForFiles}}{{/isFile}}{{^isFile}}{{{dataType}}}{{/isFile}} get{{#lambda.titlecase}}{{paramName}}{{/lambda.titlecase}}() {
return this.{{paramName}};
}

public {{#lambda.titlecase}}{{operationId}}{{/lambda.titlecase}}Param {{paramName}}(
{{#isFile}}{{#useAbstractionForFiles}}{{#collectionFormat}}java.util.Collection<org.springframework.core.io.Resource>{{/collectionFormat}}{{^collectionFormat}}org.springframework.core.io.Resource{{/collectionFormat}}{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{{dataType}}}{{/useAbstractionForFiles}}{{/isFile}}{{^isFile}}{{{dataType}}}{{/isFile}} {{paramName}}
) {
this.{{paramName}} = {{paramName}};
return this;
}

{{/allParams}}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}

if (o == null || getClass() != o.getClass()) {
return false;
}

{{#lambda.titlecase}}{{operationId}}{{/lambda.titlecase}}Param param =
({{#lambda.titlecase}}{{operationId}}{{/lambda.titlecase}}Param) o;

return {{#allParams}}{{#isByteArray}}java.util.Arrays.equals(this.{{paramName}}, param.{{paramName}}){{/isByteArray}}{{^isByteArray}}java.util.Objects.equals(this.{{paramName}}, param.{{paramName}}){{/isByteArray}}{{^-last}}
&& {{/-last}}{{/allParams}};
}

@Override
public int hashCode() {
return java.util.Objects.hash(
{{#allParams}}
{{#isByteArray}}java.util.Arrays.hashCode({{paramName}}){{/isByteArray}}{{^isByteArray}}{{paramName}}{{/isByteArray}}{{^-last}},{{/-last}}
{{/allParams}}
);
}

@Override
public String toString() {
return "{{#lambda.titlecase}}{{operationId}}{{/lambda.titlecase}}Param{values redacted}";
}
}

/**
* {{summary}}
* {{notes}}
{{#responses}}
* <p><b>{{code}}</b>{{#message}} - {{.}}{{/message}}
{{/responses}}
*
* @param params parameters for the {{operationId}} operation
{{#returnType}}
* @return {{.}}
{{/returnType}}
* @throws RestClientException if an error occurs while attempting to invoke the API
{{#externalDocs}}
* {{description}}
* @see <a href="{{url}}">{{summary}} Documentation</a>
{{/externalDocs}}
{{#isDeprecated}}
* @deprecated
{{/isDeprecated}}
*/
{{#isDeprecated}}
@Deprecated
{{/isDeprecated}}
public {{#returnType}}{{#isResponseFile}}{{#useAbstractionForFiles}}org.springframework.core.io.Resource{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{{.}}}{{/useAbstractionForFiles}}{{/isResponseFile}}{{^isResponseFile}}{{{.}}}{{/isResponseFile}} {{/returnType}}{{^returnType}}void {{/returnType}}{{operationId}}(
{{#lambda.titlecase}}{{operationId}}{{/lambda.titlecase}}Param params
) throws RestClientException {
{{#returnType}}
return {{operationId}}WithHttpInfo(params).getBody();
{{/returnType}}
{{^returnType}}
{{operationId}}WithHttpInfo(params);
{{/returnType}}
}

/**
* {{summary}}
* {{notes}}
{{#responses}}
* <p><b>{{code}}</b>{{#message}} - {{.}}{{/message}}
{{/responses}}
*
* @param params parameters for the {{operationId}} operation
* @return ResponseEntity&lt;{{returnType}}{{^returnType}}Void{{/returnType}}&gt;
* @throws RestClientException if an error occurs while attempting to invoke the API
{{#externalDocs}}
* {{description}}
* @see <a href="{{url}}">{{summary}} Documentation</a>
{{/externalDocs}}
{{#isDeprecated}}
* @deprecated
{{/isDeprecated}}
*/
{{#isDeprecated}}
@Deprecated
{{/isDeprecated}}
public ResponseEntity<{{#returnType}}{{#isResponseFile}}{{#useAbstractionForFiles}}org.springframework.core.io.Resource{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{{.}}}{{/useAbstractionForFiles}}{{/isResponseFile}}{{^isResponseFile}}{{{.}}}{{/isResponseFile}}{{/returnType}}{{^returnType}}Void{{/returnType}}> {{operationId}}WithHttpInfo(
{{#lambda.titlecase}}{{operationId}}{{/lambda.titlecase}}Param params
) throws RestClientException {
java.util.Objects.requireNonNull(
params,
"params must not be null"
);
{{#allParams}}
final {{#isFile}}{{#useAbstractionForFiles}}{{#collectionFormat}}java.util.Collection<org.springframework.core.io.Resource>{{/collectionFormat}}{{^collectionFormat}}org.springframework.core.io.Resource{{/collectionFormat}}{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{{dataType}}}{{/useAbstractionForFiles}}{{/isFile}}{{^isFile}}{{{dataType}}}{{/isFile}} {{paramName}} = params.get{{#lambda.titlecase}}{{paramName}}{{/lambda.titlecase}}();
{{/allParams}}
{{>libraries/resttemplate/withHttpInfoBody}}
}
Loading