Skip to content

Conversation

@rpanackal
Copy link
Member

@rpanackal rpanackal commented Dec 30, 2025

Context

SAP/cloud-sdk-java-backlog#464.

The parent PR contains all files as they would be if we purely relied on generation via OpenAPI code generator with commonly generated files packages with openapi-core module.

The scope of this PR is to reduce public API, achieve feature parity with resttemplate based generation and refactoring code for readability.

Feature scope:

  • Carefully removed 11 unnecessary class files
    • All auth/*.java files - We support authentication via destination
    • ApiException removed in favour existing OpenApiRequestException (modified)
    • ServerConfiguration, ServerVariable, StringUtil removed as we do not support single client instance pointing to multi urls
    • apache/RFC3339*.java classes removed in favor of reusing apiClient/RFC3339DateFormat
  • Reduce public api in BaseApi

Improvements in ApiClient

  • Public api removed
    • defaultHeaderMaps: headers expected to be set request level, destination header provider or custom ClosableHttpClient
    • defaultCookieMap: no cookie support
    • servers, serverIndex, serverVariables: only single baseUrl support
    • lastStatusCode, lastResponseHeaders: Removed due to feature engineering concerns. To compensate, new api introduced in OpenApiRequestException and new OpenApiResponse.
    • debugging flag, connectionTimeout: useless and to be configured elsewhere.
    • cookieParams and authNames that sets request level configuration for cookies and authorization (but unused) are removed from invokeAPI signature
  • All api not used by generated classes are now set to the strictest access possible.
  • @Beta on jackson exposing api
  • All public api that doesn't rely/modify on internal state is now static
  • Move out all response handling logic into new package private class DefaultApiResponseHandler
  • ctors replaced/hidden with static factory methods
  • No-args ctor introduced (deviation from resttemplate)
  • Make ApiClient a almost @Value class
  • Fix url building handle egde case "basePath/" + "/v2" = "basePath//v2"
  • Vulnerability fix to remove serializing payload onto Exception messages

Feature Parity with resttemplate (template modifications)

  • Object mapper configuration
  • Nullability annotation and final on local vars, parameters, returns as appropriate.
  • Javadoc improvements
  • Destination based ctor and ai sdk ctor support
  • Method overloading per operation (get, post, etc) for optional and required params
  • Vendor extension support x-sap-cloud-sdk-operation-name, x-return-nullable
  • Support apache/OpenApiResponse instead of void as return type for remote calls. Existing core/OpenApiResponse has Spring components in public contract. 😿

Definition of Done

  • Functionality scope stated & covered
  • Tests cover the scope above
  • Error handling created / updated & covered by the tests above
  • Documentation updated
  • Release notes updated

- no more shared client in *Api.java instances
- *Api.invoke method bugged and unused
- Remove debugging, connectionTimeout, defaultHeaderMap, defaultCookieMap
- add TODOs
- public setBasePath
- Remove addDefaultHeader, setUserAgent,
- Make as manny methods static
- Remove deprecated getStatusCode and getResponseHeaders
- public parameterToPairs
- Make as many methods static
- rename ApiClientResponseHandler to DefaultApiResponseHandler
- finish up ApiClient todos
- Enhance JavaDoc
- Support Vendor extension `x-sap-cloud-sdk-operation-name`
- Method overloading for required and options param in operations
return this;
}
return fromHttpClient((CloseableHttpClient) ApacheHttpClient5Accessor.getHttpClient(destination))
.withBasePath(destination.asHttp().getUri().toString());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Minor)

I'm not sure whether the following is unnecessary: withBasePath(destination.asHttp().getUri().toString())

unit tests will show.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is neccessary, otherwise we will have DEFAULT_BASE_PATH as basePath.

import lombok.Value;
import lombok.With;

@Value
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Minor)

Happy about making it an immuatable class!
Unfortunately it's final implicitly, meaning it can never be customized e.g. for future workarounds. Potential solution could be non-value or introduction of interface.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made the class almost @Value by making the class non-final.

protected DateFormat dateFormat;
@With
@Nullable
String tempFolderPath;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Minor)

You mentioned you want this field to have public getter (?)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only basePath has a getter right now. tempFolderPath is null by default.

* {{#appDescription}}{{{appDescription}}}{{/appDescription}}{{^appDescription}}No description provided.{{/appDescription}}
*/
{{!>generatedAnnotation}}
{{^isReleased}}@Beta{{/isReleased}}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Minor)

Please use fully-qualified-name for optional (deendency) anotations, e.g.

@com.google.common.annotations.Beta

@newtork newtork added the please review Request to review a pull request label Dec 30, 2025
@rpanackal rpanackal changed the title refactor: [OpenAPI] Refactor Apache related files and templates refactor: [OpenAPI] Part 1: Refactor Apache related files and templates Jan 7, 2026
- Make ApiClient almost `@Value`
- fix url building with "//"
- Fix vulnerabilities of payload leak in exception messages
Copy link
Member Author

@rpanackal rpanackal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:)

return this;
}
return fromHttpClient((CloseableHttpClient) ApacheHttpClient5Accessor.getHttpClient(destination))
.withBasePath(destination.asHttp().getUri().toString());
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is neccessary, otherwise we will have DEFAULT_BASE_PATH as basePath.

import lombok.Value;
import lombok.With;

@Value
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made the class almost @Value by making the class non-final.

protected DateFormat dateFormat;
@With
@Nullable
String tempFolderPath;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only basePath has a getter right now. tempFolderPath is null by default.

Copy link
Member Author

@rpanackal rpanackal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some screenshots for supporting the PR

  1. Removes following 5 dependencies (Image from AI SDK Prompt Registry pom.xml)
Image
  1. Shows how an api method will change effectively
Image

@rpanackal rpanackal self-assigned this Jan 8, 2026
Copy link
Contributor

@newtork newtork left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!
As discussed we'll have a follow up for:

  • tests - see Part 2 PR
  • response headers + code - wip

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

please review Request to review a pull request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants