Skip to content

Commit b59957a

Browse files
authored
Java API invocation flexibility (OpenAPITools#18078)
* add direct invocation methods for java (httpclient) * add direct invocation methods for java (resttemplate) * handle methods only if endpoints exist for api client * preserve previous newline to minimize changes * update httpclient/resttemplate samples * add common methods in base class * regenerate samples with base class
1 parent da1187f commit b59957a

70 files changed

Lines changed: 2500 additions & 590 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaClientCodegen.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,10 @@ public void processOpts() {
569569
supportingFiles.add(new SupportingFile("auth/Authentication.mustache", authFolder, "Authentication.java"));
570570
}
571571

572+
if (APACHE.equals(getLibrary()) || RESTTEMPLATE.equals(getLibrary())) {
573+
supportingFiles.add(new SupportingFile("BaseApi.mustache", invokerFolder, "BaseApi.java"));
574+
}
575+
572576
if (FEIGN.equals(getLibrary())) {
573577
if (getSerializationLibrary() == null) {
574578
LOGGER.info("No serializationLibrary configured, using '{}' as fallback", SERIALIZATION_LIBRARY_JACKSON);

modules/openapi-generator/src/main/resources/Java/libraries/apache-httpclient/ApiClient.mustache

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -916,15 +916,11 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
916916
}
917917

918918
/**
919-
* Build full URL by concatenating base path, the given sub path and query parameters.
919+
* Returns the URL of the client as defined by the server (if exists) or the base path.
920920
*
921-
* @param path The sub path
922-
* @param queryParams The query parameters
923-
* @param collectionQueryParams The collection query parameters
924-
* @param urlQueryDeepObject URL query string of the deep object parameters
925-
* @return The full URL
921+
* @return The URL for the client.
926922
*/
927-
private String buildUrl(String path, List<Pair> queryParams, List<Pair> collectionQueryParams, String urlQueryDeepObject) {
923+
public String getBaseURL() {
928924
String baseURL;
929925
if (serverIndex != null) {
930926
if (serverIndex < 0 || serverIndex >= servers.size()) {
@@ -936,6 +932,20 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
936932
} else {
937933
baseURL = basePath;
938934
}
935+
return baseURL;
936+
}
937+
938+
/**
939+
* Build full URL by concatenating base URL, the given sub path and query parameters.
940+
*
941+
* @param path The sub path
942+
* @param queryParams The query parameters
943+
* @param collectionQueryParams The collection query parameters
944+
* @param urlQueryDeepObject URL query string of the deep object parameters
945+
* @return The full URL
946+
*/
947+
private String buildUrl(String path, List<Pair> queryParams, List<Pair> collectionQueryParams, String urlQueryDeepObject) {
948+
String baseURL = getBaseURL();
939949
940950
final StringBuilder url = new StringBuilder();
941951
url.append(baseURL).append(path);
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
{{>licenseInfo}}
2+
package {{invokerPackage}};
3+
4+
import com.fasterxml.jackson.core.type.TypeReference;
5+
6+
import java.util.Collections;
7+
import java.util.Map;
8+
9+
{{>generatedAnnotation}}
10+
public abstract class BaseApi {
11+
12+
protected ApiClient apiClient;
13+
14+
public BaseApi() {
15+
this(Configuration.getDefaultApiClient());
16+
}
17+
18+
public BaseApi(ApiClient apiClient) {
19+
this.apiClient = apiClient;
20+
}
21+
22+
public ApiClient getApiClient() {
23+
return apiClient;
24+
}
25+
26+
public void setApiClient(ApiClient apiClient) {
27+
this.apiClient = apiClient;
28+
}
29+
30+
/**
31+
* Directly invoke the API for the given URL. Useful if the API returns direct links/URLs for subsequent requests.
32+
* @param url The URL for the request, either full URL or only the path.
33+
* @param method The HTTP method for the request.
34+
* @throws ApiException if fails to make API call.
35+
*/
36+
public void invokeAPI(String url, String method) throws ApiException {
37+
invokeAPI(url, method, null, null, Collections.emptyMap());
38+
}
39+
40+
/**
41+
* Directly invoke the API for the given URL. Useful if the API returns direct links/URLs for subsequent requests.
42+
* @param url The URL for the request, either full URL or only the path.
43+
* @param method The HTTP method for the request.
44+
* @param additionalHeaders Additional headers for the request.
45+
* @throws ApiException if fails to make API call.
46+
*/
47+
public void invokeAPI(String url, String method, Map<String, String> additionalHeaders) throws ApiException {
48+
invokeAPI(url, method, null, null, additionalHeaders);
49+
}
50+
51+
/**
52+
* Directly invoke the API for the given URL. Useful if the API returns direct links/URLs for subsequent requests.
53+
* @param url The URL for the request, either full URL or only the path.
54+
* @param method The HTTP method for the request.
55+
* @param request The request object.
56+
* @throws ApiException if fails to make API call.
57+
*/
58+
public void invokeAPI(String url, String method, Object request) throws ApiException {
59+
invokeAPI(url, method, request, null, Collections.emptyMap());
60+
}
61+
62+
/**
63+
* Directly invoke the API for the given URL. Useful if the API returns direct links/URLs for subsequent requests.
64+
* @param url The URL for the request, either full URL or only the path.
65+
* @param method The HTTP method for the request.
66+
* @param request The request object.
67+
* @param additionalHeaders Additional headers for the request.
68+
* @throws ApiException if fails to make API call.
69+
*/
70+
public void invokeAPI(String url, String method, Object request, Map<String, String> additionalHeaders) throws ApiException {
71+
invokeAPI(url, method, request, null, additionalHeaders);
72+
}
73+
74+
/**
75+
* Directly invoke the API for the given URL. Useful if the API returns direct links/URLs for subsequent requests.
76+
* @param url The URL for the request, either full URL or only the path.
77+
* @param method The HTTP method for the request.
78+
* @param returnType The return type.
79+
* @return The API response in the specified type.
80+
* @throws ApiException if fails to make API call.
81+
*/
82+
public <T> T invokeAPI(String url, String method, TypeReference<T> returnType) throws ApiException {
83+
return invokeAPI(url, method, null, returnType, Collections.emptyMap());
84+
}
85+
86+
/**
87+
* Directly invoke the API for the given URL. Useful if the API returns direct links/URLs for subsequent requests.
88+
* @param url The URL for the request, either full URL or only the path.
89+
* @param method The HTTP method for the request.
90+
* @param request The request object.
91+
* @param returnType The return type.
92+
* @return The API response in the specified type.
93+
* @throws ApiException if fails to make API call.
94+
*/
95+
public <T> T invokeAPI(String url, String method, Object request, TypeReference<T> returnType) throws ApiException {
96+
return invokeAPI(url, method, request, returnType, Collections.emptyMap());
97+
}
98+
99+
/**
100+
* Directly invoke the API for the given URL. Useful if the API returns direct links/URLs for subsequent requests.
101+
* @param url The URL for the request, either full URL or only the path.
102+
* @param method The HTTP method for the request.
103+
* @param request The request object.
104+
* @param returnType The return type.
105+
* @param additionalHeaders Additional headers for the request.
106+
* @return The API response in the specified type.
107+
* @throws ApiException if fails to make API call.
108+
*/
109+
public abstract <T> T invokeAPI(String url, String method, Object request, TypeReference<T> returnType, Map<String, String> additionalHeaders) throws ApiException;
110+
}

modules/openapi-generator/src/main/resources/Java/libraries/apache-httpclient/api.mustache

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import com.fasterxml.jackson.core.type.TypeReference;
55

66
import {{invokerPackage}}.ApiException;
77
import {{invokerPackage}}.ApiClient;
8+
import {{invokerPackage}}.BaseApi;
89
import {{invokerPackage}}.Configuration;
910
{{#models.0}}
1011
import {{modelPackage}}.*;
@@ -24,25 +25,14 @@ import java.util.StringJoiner;
2425

2526
{{>generatedAnnotation}}
2627
{{#operations}}
27-
public class {{classname}} {
28-
29-
30-
private ApiClient apiClient;
28+
public class {{classname}} extends BaseApi {
3129
3230
public {{classname}}() {
33-
this(Configuration.getDefaultApiClient());
31+
super(Configuration.getDefaultApiClient());
3432
}
3533

3634
public {{classname}}(ApiClient apiClient) {
37-
this.apiClient = apiClient;
38-
}
39-
40-
public ApiClient getApiClient() {
41-
return apiClient;
42-
}
43-
44-
public void setApiClient(ApiClient apiClient) {
45-
this.apiClient = apiClient;
35+
super(apiClient);
4636
}
4737

4838
{{#operation}}
@@ -201,6 +191,48 @@ public class {{classname}} {
201191
);
202192
}
203193

194+
{{#-last}}
195+
@Override
196+
public <T> T invokeAPI(String url, String method, Object request, TypeReference<T> returnType, Map<String, String> additionalHeaders) throws ApiException {
197+
String localVarPath = url.replace(apiClient.getBaseURL(), "");
198+
StringJoiner localVarQueryStringJoiner = new StringJoiner("&");
199+
List<Pair> localVarQueryParams = new ArrayList<Pair>();
200+
List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
201+
Map<String, String> localVarHeaderParams = new HashMap<String, String>();
202+
Map<String, String> localVarCookieParams = new HashMap<String, String>();
203+
Map<String, Object> localVarFormParams = new HashMap<String, Object>();
204+
205+
localVarHeaderParams.putAll(additionalHeaders);
206+
207+
final String[] localVarAccepts = {
208+
{{#produces}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/produces}}
209+
};
210+
final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
211+
212+
final String[] localVarContentTypes = {
213+
{{#consumes}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/consumes}}
214+
};
215+
final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
216+
217+
String[] localVarAuthNames = new String[] { {{#authMethods}}"{{name}}"{{^-last}}, {{/-last}}{{/authMethods}} };
218+
219+
return apiClient.invokeAPI(
220+
localVarPath,
221+
method,
222+
localVarQueryParams,
223+
localVarCollectionQueryParams,
224+
localVarQueryStringJoiner.toString(),
225+
request,
226+
localVarHeaderParams,
227+
localVarCookieParams,
228+
localVarFormParams,
229+
localVarAccept,
230+
localVarContentType,
231+
localVarAuthNames,
232+
returnType
233+
);
234+
}
235+
{{/-last}}
204236
{{/operation}}
205237
}
206238
{{/operations}}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package {{invokerPackage}};
2+
3+
import org.springframework.web.client.RestClientException;
4+
import org.springframework.core.ParameterizedTypeReference;
5+
import org.springframework.http.HttpMethod;
6+
import org.springframework.http.ResponseEntity;
7+
8+
{{>generatedAnnotation}}
9+
public abstract class BaseApi {
10+
11+
protected ApiClient apiClient;
12+
13+
public BaseApi() {
14+
this(new ApiClient());
15+
}
16+
17+
public BaseApi(ApiClient apiClient) {
18+
this.apiClient = apiClient;
19+
}
20+
21+
public ApiClient getApiClient() {
22+
return apiClient;
23+
}
24+
25+
public void setApiClient(ApiClient apiClient) {
26+
this.apiClient = apiClient;
27+
}
28+
29+
/**
30+
* Directly invoke the API for the given URL. Useful if the API returns direct links/URLs for subsequent requests.
31+
* @param url The URL for the request, either full URL or only the path.
32+
* @param method The HTTP method for the request.
33+
* @return ResponseEntity&lt;Void&gt;
34+
* @throws RestClientException if an error occurs while attempting to invoke the API
35+
*/
36+
public ResponseEntity<Void> invokeAPI(String url, HttpMethod method) throws RestClientException {
37+
return invokeAPI(url, method, null, new ParameterizedTypeReference<Void>() {});
38+
}
39+
40+
/**
41+
* Directly invoke the API for the given URL. Useful if the API returns direct links/URLs for subsequent requests.
42+
* @param url The URL for the request, either full URL or only the path.
43+
* @param method The HTTP method for the request.
44+
* @param request The request object.
45+
* @return ResponseEntity&lt;Void&gt;
46+
* @throws RestClientException if an error occurs while attempting to invoke the API
47+
*/
48+
public ResponseEntity<Void> invokeAPI(String url, HttpMethod method, Object request) throws RestClientException {
49+
return invokeAPI(url, method, request, new ParameterizedTypeReference<Void>() {});
50+
}
51+
52+
/**
53+
* Directly invoke the API for the given URL. Useful if the API returns direct links/URLs for subsequent requests.
54+
* @param url The URL for the request, either full URL or only the path.
55+
* @param method The HTTP method for the request.
56+
* @param returnType The return type.
57+
* @return ResponseEntity in the specified type.
58+
* @throws RestClientException if an error occurs while attempting to invoke the API
59+
*/
60+
public <T> ResponseEntity<T> invokeAPI(String url, HttpMethod method, ParameterizedTypeReference<T> returnType) throws RestClientException {
61+
return invokeAPI(url, method, null, returnType);
62+
}
63+
64+
/**
65+
* Directly invoke the API for the given URL. Useful if the API returns direct links/URLs for subsequent requests.
66+
* @param url The URL for the request, either full URL or only the path.
67+
* @param method The HTTP method for the request.
68+
* @param request The request object.
69+
* @param returnType The return type.
70+
* @return ResponseEntity in the specified type.
71+
* @throws RestClientException if an error occurs while attempting to invoke the API
72+
*/
73+
public abstract <T> ResponseEntity<T> invokeAPI(String url, HttpMethod method, Object request, ParameterizedTypeReference<T> returnType) throws RestClientException;
74+
}

modules/openapi-generator/src/main/resources/Java/libraries/resttemplate/api.mustache

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package {{package}};
22

33
import {{invokerPackage}}.ApiClient;
4+
import {{invokerPackage}}.BaseApi;
45

56
{{#imports}}import {{import}};
67
{{/imports}}
@@ -31,26 +32,17 @@ import org.springframework.http.ResponseEntity;
3132
@Component("{{package}}.{{classname}}")
3233
{{/generateClientAsBean}}
3334
{{#operations}}
34-
public class {{classname}} {
35-
private ApiClient apiClient;
35+
public class {{classname}} extends BaseApi {
3636
3737
public {{classname}}() {
38-
this(new ApiClient());
38+
super(new ApiClient());
3939
}
4040

4141
{{#generateClientAsBean}}
4242
@Autowired
4343
{{/generateClientAsBean}}
4444
public {{classname}}(ApiClient apiClient) {
45-
this.apiClient = apiClient;
46-
}
47-
48-
public ApiClient getApiClient() {
49-
return apiClient;
50-
}
51-
52-
public void setApiClient(ApiClient apiClient) {
53-
this.apiClient = apiClient;
45+
super(apiClient);
5446
}
5547

5648
{{#operation}}
@@ -159,6 +151,33 @@ public class {{classname}} {
159151
{{#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}}
160152
return apiClient.invokeAPI("{{{path}}}", HttpMethod.{{httpMethod}}, {{#hasPathParams}}uriVariables{{/hasPathParams}}{{^hasPathParams}}Collections.<String, Object>emptyMap(){{/hasPathParams}}, localVarQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAccept, localVarContentType, localVarAuthNames, localReturnType);
161153
}
154+
{{#-last}}
155+
156+
@Override
157+
public <T> ResponseEntity<T> invokeAPI(String url, HttpMethod method, Object request, ParameterizedTypeReference<T> returnType) throws RestClientException {
158+
String localVarPath = url.replace(apiClient.getBasePath(), "");
159+
Object localVarPostBody = request;
160+
161+
final Map<String, Object> uriVariables = new HashMap<String, Object>();
162+
final MultiValueMap<String, String> localVarQueryParams = new LinkedMultiValueMap<String, String>();
163+
final HttpHeaders localVarHeaderParams = new HttpHeaders();
164+
final MultiValueMap<String, String> localVarCookieParams = new LinkedMultiValueMap<String, String>();
165+
final MultiValueMap<String, Object> localVarFormParams = new LinkedMultiValueMap<String, Object>();
166+
167+
final String[] localVarAccepts = { {{#hasProduces}}
168+
{{#produces}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/produces}}
169+
{{/hasProduces}} };
170+
final List<MediaType> localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
171+
final String[] localVarContentTypes = { {{#hasConsumes}}
172+
{{#consumes}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/consumes}}
173+
{{/hasConsumes}} };
174+
final MediaType localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
175+
176+
String[] localVarAuthNames = new String[] { {{#authMethods}}"{{name}}"{{^-last}}, {{/-last}}{{/authMethods}} };
177+
178+
return apiClient.invokeAPI(localVarPath, method, uriVariables, localVarQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAccept, localVarContentType, localVarAuthNames, returnType);
179+
}
180+
{{/-last}}
162181
{{/operation}}
163182
}
164183
{{/operations}}

0 commit comments

Comments
 (0)