Skip to content

feat/idr-rate-aggregator-habibullah-dzaky#175

Open
habibullahdm wants to merge 1 commit intoallobankdev:mainfrom
habibullahdm:feat/idr-rate-aggregator
Open

feat/idr-rate-aggregator-habibullah-dzaky#175
habibullahdm wants to merge 1 commit intoallobankdev:mainfrom
habibullahdm:feat/idr-rate-aggregator

Conversation

@habibullahdm
Copy link

  1. Polymorphism Justification (Strategy Pattern)
    The Strategy Pattern was implemented to decouple the resource processing logic from the main service layer. While a conditional block (if-else or switch) would suffice for current requirements, the pattern provides:

Open/Closed Principle: New resource types can be added by simply creating a new strategy class without modifying existing service logic.

Separation of Concerns: Each strategy encapsulates the specific parsing and validation logic for one resource, preventing the service layer from becoming a "God Class."

Testability: Each strategy can be unit-tested in isolation, reducing the complexity of testing the entire service flow.

  1. Client Factory (FactoryBean)
    A FactoryBean was chosen to manage the construction of the external API client for the following reasons:

Complex Initialization: The client requires sophisticated setup (e.g., custom interceptors, specific timeouts, and SSL configurations) that is cleaner to encapsulate within a dedicated factory class rather than a bloated @bean method.

Encapsulation: It hides the "how-to" of client creation. If the underlying library for the client changes (e.g., switching from RestTemplate to WebClient), the change is localized to the factory.

Control over Lifecycle: FactoryBean provides a more robust way to handle singleton vs. prototype instances and asynchronous initialization if required by the external dependency.

  1. Startup Runner Choice (ApplicationRunner)
    The choice of ApplicationRunner over @PostConstruct for initial data ingestion is intentional because:

Context Readiness: @PostConstruct triggers before the Spring ApplicationContext is fully refreshed. If the ingestion process requires interaction with other beans or the database, it may lead to NullPointerException or incomplete transactions.

Application Arguments: ApplicationRunner provides native access to command-line arguments, allowing us to pass specific flags (e.g., --skip-ingestion) during startup.

Graceful Failure: Unlike @PostConstruct, which can block the entire bean creation lifecycle, an ApplicationRunner ensures the application is up and running before the heavy lifting of data ingestion starts.

…ers, services, integration modules, configuration, exception handling, DTOs, and tests.
@habibullahdm
Copy link
Author

Scenario Evidende
success resourceType = latest_idr_rates Screenshot 2026-02-27 at 2 14 55 PM
success resourceType = historical_idr_usd Screenshot 2026-02-27 at 2 16 32 PM
success resourceType = supported_currencies Screenshot 2026-02-27 at 2 16 45 PM
error Screenshot 2026-02-27 at 2 16 12 PM

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant