Feat/idr-rate-aggregator-cory#155
Open
cory-work-tech wants to merge 23 commits intoallobankdev:mainfrom
Open
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🏛 Architectural Rationale
1. Polymorphism & Strategy Pattern for Data Fetching
Instead of using conditional blocks (
if-else/switch) in the service layer to handle different data resources, the Strategy Pattern (FinancialDataStrategyinterface + concrete implementations) was deliberately chosen.Justification & Benefits:
Extensibility
Adding a new financial data source requires only creating a new class that implements
FinancialDataStrategy. No modification needed inStartupDataRunneror other existing strategies → Open/Closed Principle satisfied.Maintainability
Each strategy is self-contained → encapsulates logic for one resource only. Improves readability, simplifies debugging, and allows isolated unit testing. A growing switch/if-else block would become large, hard to read and error-prone.
Separation of Concerns
High-level algorithm (iterating strategies + storing results in
StartupDataRunner) is completely decoupled from the specific fetch/transform logic of each resource.2. Client Factory: Why
FactoryBean<RestTemplate>over plain@Bean?A
FactoryBean<RestTemplate>was implemented instead of a simple@Beanmethod to encapsulate complex client initialization.Detailed Reasons:
Custom Initialization Control
FactoryBeanallows centralized construction, configuration, and normalization of theRestTemplatein a dedicated class — far beyond what a simple bean method provides.Encapsulation of Complexity
Handles externalized API base URL (from
application.yml) and appliesUriTemplateHandlerso all strategies automatically benefit from a pre-configured root path.Separation of Concerns
Decouples the definition of the
RestTemplatefrom the network/configuration logic (timeouts, base paths, interceptors…). Keeps@Configurationclasses much cleaner.Proxying & Lifecycle Hook
FactoryBeanintegrates deeply into Spring’s bean creation lifecycle — ideal when construction involves significant setup logic that would otherwise clutter configuration classes.3. Startup Runner: Why
ApplicationRunnerover@PostConstruct?ApplicationRunnerwas chosen (viaStartupDataRunner) for initial data ingestion instead of using@PostConstructmethods.Complete Justification:
Context Full Readiness
@PostConstructruns during bean initialization — often too early. The fullApplicationContext(proxies, AOP, logging, networking components…) may not be completely ready yet.Access to ApplicationArguments
ApplicationRunnerreceives command-line arguments → enables future flexibility (e.g. selective loading via flags).Failure Resilience
If the external Frankfurter API is unavailable, an exception in
@PostConstructcan crash the entire application startup.ApplicationRunnerexecutes later → allows graceful error handling so the JVM & application can finish starting even when initial data load fails.Service Availability Guarantee
Runs only after all beans are created and the application is ready to accept traffic → guarantees
InMemoryDataStoreService(and all dependencies) are fully available & properly injected when fetching begins.