<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Thompson Olufemi</title>
    <description>The latest articles on DEV Community by Thompson Olufemi (@thompsonolufemi).</description>
    <link>https://dev.to/thompsonolufemi</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2298608%2F22e0cabd-9bbd-44f9-9252-f558e88d869a.jpg</url>
      <title>DEV Community: Thompson Olufemi</title>
      <link>https://dev.to/thompsonolufemi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/thompsonolufemi"/>
    <language>en</language>
    <item>
      <title>[Boost]</title>
      <dc:creator>Thompson Olufemi</dc:creator>
      <pubDate>Fri, 20 Mar 2026 15:01:42 +0000</pubDate>
      <link>https://dev.to/thompsonolufemi/-10f2</link>
      <guid>https://dev.to/thompsonolufemi/-10f2</guid>
      <description>&lt;div class="ltag__link"&gt;
  &lt;a href="/thompsonolufemi" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2298608%2F22e0cabd-9bbd-44f9-9252-f558e88d869a.jpg" alt="thompsonolufemi"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/thompsonolufemi/-419i" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;[Boost]&lt;/h2&gt;
      &lt;h3&gt;Thompson Olufemi ・ Mar 16&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#cli&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#terminal&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#devops&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#software&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>cli</category>
      <category>terminal</category>
      <category>devops</category>
      <category>software</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>Thompson Olufemi</dc:creator>
      <pubDate>Mon, 16 Mar 2026 05:15:05 +0000</pubDate>
      <link>https://dev.to/thompsonolufemi/-419i</link>
      <guid>https://dev.to/thompsonolufemi/-419i</guid>
      <description>&lt;div class="ltag__link"&gt;
  &lt;a href="/thompsonolufemi" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2298608%2F22e0cabd-9bbd-44f9-9252-f558e88d869a.jpg" alt="thompsonolufemi"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/thompsonolufemi/cmdlib-save-search-and-run-terminal-commands-with-descriptions-better-than-ctrlr-1ngm" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;cmdlib: Save, Search and Run Terminal Commands with Descriptions (Better Than CTRL+R)&lt;/h2&gt;
      &lt;h3&gt;Thompson Olufemi ・ Mar 16&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#cli&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#terminal&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#devops&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#software&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>cli</category>
      <category>terminal</category>
      <category>devops</category>
      <category>software</category>
    </item>
    <item>
      <title>cmdlib: Save, Search and Run Terminal Commands with Descriptions (Better Than CTRL+R)</title>
      <dc:creator>Thompson Olufemi</dc:creator>
      <pubDate>Mon, 16 Mar 2026 05:11:25 +0000</pubDate>
      <link>https://dev.to/thompsonolufemi/cmdlib-save-search-and-run-terminal-commands-with-descriptions-better-than-ctrlr-1ngm</link>
      <guid>https://dev.to/thompsonolufemi/cmdlib-save-search-and-run-terminal-commands-with-descriptions-better-than-ctrlr-1ngm</guid>
      <description>&lt;p&gt;If you use the terminal a lot, you probably run into this problem.&lt;/p&gt;

&lt;p&gt;You ran a useful command some time ago. Maybe last week or last month. Now you need it again but you cannot remember the exact command.&lt;/p&gt;

&lt;p&gt;So you press CTRL+R and start searching through your shell history.&lt;/p&gt;

&lt;p&gt;Sometimes you find it quickly. Many times you don't. Or you remember what the command does but you do not remember the exact text of the command.&lt;/p&gt;

&lt;p&gt;This happens to me all the time.&lt;/p&gt;

&lt;p&gt;For example I might remember something like&lt;/p&gt;

&lt;p&gt;"that command that deletes docker images"&lt;/p&gt;

&lt;p&gt;or&lt;/p&gt;

&lt;p&gt;"that command that finds large files in a folder"&lt;/p&gt;

&lt;p&gt;But when I search with CTRL+R it does not help because I do not remember the exact command text.&lt;/p&gt;

&lt;p&gt;So I built a small tool for myself called &lt;strong&gt;&lt;em&gt;cmdlib&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;cmdlib is a very simple idea.&lt;/p&gt;

&lt;p&gt;It lets you save commands with a description and later search using that description.&lt;/p&gt;

&lt;p&gt;For example you can write a command like : &lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker image prune -a&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And then add a meaninful description : &lt;/p&gt;

&lt;p&gt;&lt;code&gt;delete unused docker image&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Later when you forget the command you can just search :&lt;/p&gt;

&lt;p&gt;&lt;code&gt;delete docker&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;and &lt;strong&gt;&lt;em&gt;cmdlib&lt;/em&gt;&lt;/strong&gt; will show it.&lt;/p&gt;

&lt;p&gt;You can then press Enter and run it directly.&lt;/p&gt;

&lt;p&gt;So it works like a personal command library for your terminal.&lt;/p&gt;

&lt;p&gt;You can save commands you use often. You can add a small description so you remember what they do. Then you can search them anytime.&lt;/p&gt;

&lt;p&gt;Some things you can do with &lt;strong&gt;&lt;em&gt;cmdlib&lt;/em&gt;&lt;/strong&gt; : &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Save useful commands with descriptions&lt;/li&gt;
&lt;li&gt;Search commands using normal words&lt;/li&gt;
&lt;li&gt;Run the command directly from the search results&lt;/li&gt;
&lt;li&gt;Delete commands you no longer need&lt;/li&gt;
&lt;li&gt;Browse your shell history and save commands from there&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The workflow is very simple.&lt;/p&gt;

&lt;p&gt;Install it by running the following command in your terminal.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm install -g cmdlib&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then After installing, &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;restart your terminal &lt;/li&gt;
&lt;li&gt;or run &lt;code&gt;source ~/.bashrc&lt;/code&gt;  if using bash shell &lt;/li&gt;
&lt;li&gt;or run &lt;code&gt;source ~/.zshrc&lt;/code&gt;if using zsh shell&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then type &lt;code&gt;cmdlib&lt;/code&gt; in your terminal to start using it.&lt;/p&gt;

&lt;p&gt;Once you run it, it opens a small interactive search interface in your terminal where you can search, save, and run commands easily.&lt;/p&gt;

&lt;p&gt;It is a small tool, but it has been very useful for me because I no longer forget commands that took time to figure out.&lt;/p&gt;

&lt;p&gt;If you want to try it, you can install it from npm.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm install -g cmdlib&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You can also checkout the README on the GitHub page for instructions on how to use it:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/olufemithompson/cmdlib" rel="noopener noreferrer"&gt;https://github.com/olufemithompson/cmdlib&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you find it useful, please consider giving the repo a star on GitHub. It helps others discover the project.&lt;/p&gt;

&lt;p&gt;If you try it and have suggestions or ideas for improvements, I would love to hear them. Contributions and feedback are always welcome.&lt;/p&gt;

</description>
      <category>cli</category>
      <category>terminal</category>
      <category>devops</category>
      <category>node</category>
    </item>
    <item>
      <title>Building Resilient Distributed Systems with Springboot</title>
      <dc:creator>Thompson Olufemi</dc:creator>
      <pubDate>Thu, 02 Jan 2025 11:36:42 +0000</pubDate>
      <link>https://dev.to/thompsonolufemi/building-resilient-distributed-systems-with-springboot-52ln</link>
      <guid>https://dev.to/thompsonolufemi/building-resilient-distributed-systems-with-springboot-52ln</guid>
      <description>&lt;p&gt;When building distributed systems, many teams concentrate on making individual services strong and reliable. While that's important, the real challenge lies in how these services interact, especially when the system is under heavy stress. &lt;/p&gt;

&lt;p&gt;A resilient system isn't just about tough services - it's about ensuring all parts of the system work together smoothly when things go wrong.&lt;/p&gt;

&lt;p&gt;Now, if you're a Spring Boot developer like me, you're in luck. &lt;/p&gt;

&lt;p&gt;In this article, I'll not only break down four essential strategies for building resilient systems, but I'll also provide sample code snippets, showing you how to implement them with Spring Boot libraries and tools. &lt;/p&gt;

&lt;p&gt;Let's get started.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Prioritize Performance with Caching
&lt;/h2&gt;

&lt;p&gt;When your application is flooded with requests, where does it break first? Often, it’s the database or an external API. Caching is the go-to solution to ease this bottleneck by storing frequently accessed data closer to your application.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Caching Matters
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Speed&lt;/strong&gt;: A cache retrieves data faster than a database or an API call. Faster responses mean happier users.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reliability&lt;/strong&gt;: Even if your database or API is temporarily unavailable, a cache can keep things running smoothly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability&lt;/strong&gt;: Reducing database hits means your system can handle more traffic without crumbling under pressure.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Common Use Cases for Caching
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Static Data&lt;/strong&gt;: Product catalogs, user preferences, or site configurations that don’t change frequently.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Computed Data&lt;/strong&gt;: Expensive calculations, like recommendation engines or data aggregations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Session Management&lt;/strong&gt;: Tracking user sessions or authentication tokens.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Implementing Caching in Spring Boot
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Step 1: Add Caching Dependencies
&lt;/h4&gt;

&lt;p&gt;For basic caching, include this in your &lt;code&gt;pom.xml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;spring-boot-starter-cache&amp;lt;/artifactId&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want distributed caching with Redis:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;spring-boot-starter-data-redis&amp;lt;/artifactId&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step 2: Enable Caching
&lt;/h4&gt;

&lt;p&gt;Enable caching in your application by adding &lt;code&gt;@EnableCaching&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@SpringBootApplication
@EnableCaching
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step 3: Define Cacheable Methods
&lt;/h4&gt;

&lt;p&gt;Use &lt;code&gt;@Cacheable&lt;/code&gt; to specify which methods should cache their results:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Service
public class WeatherService {

    @Cacheable("weather")
    public String getWeather(String location) {
        // Simulate slow external API call
        slowApiCall();
        return "Sunny in " + location;
    }

    private void slowApiCall() {
        //api call code
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step 4: Configure Cache Settings
&lt;/h4&gt;

&lt;p&gt;For Redis, add this to application.properties:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;spring.cache.type=redis
spring.redis.host=localhost
spring.redis.port=6379
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Graceful Recovery with Circuit Breakers
&lt;/h2&gt;

&lt;p&gt;Failures are inevitable in distributed systems. The trick is to isolate those failures and prevent them from dragging down the rest of the system. This is where circuit breakers shine.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is a Circuit Breaker?
&lt;/h3&gt;

&lt;p&gt;A circuit breaker monitors your service calls. If too many failures occur, it trips, temporarily stopping further calls. This prevents overloading a struggling service and allows it time to recover.&lt;/p&gt;

&lt;h3&gt;
  
  
  When to Use Circuit Breakers
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;When calling external APIs or microservices that are prone to latency or failures.&lt;/li&gt;
&lt;li&gt;To protect critical parts of your system from cascading failures.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Using Circuit Breakers with Resilience4j in Spring Boot
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Step 1: Add Dependencies
&lt;/h4&gt;

&lt;p&gt;Add Resilience4j to your project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;io.github.resilience4j&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;resilience4j-spring-boot2&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;1.7.1&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step 2: Configure Circuit Breakers
&lt;/h4&gt;

&lt;p&gt;Define your circuit breaker settings in &lt;code&gt;application.properties&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;resilience4j.circuitbreaker.instances.myService.failure-rate-threshold=50
resilience4j.circuitbreaker.instances.myService.sliding-window-size=10
resilience4j.circuitbreaker.instances.myService.wait-duration-in-open-state=10000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step 3: Wrap Calls with Circuit Breakers
&lt;/h4&gt;

&lt;p&gt;Use &lt;code&gt;@CircuitBreaker&lt;/code&gt; to wrap risky service calls:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@RestController
public class ApiController {

    @CircuitBreaker(name = "myService", fallbackMethod = "fallbackResponse")
    @GetMapping("/data")
    public String fetchData() {
        // Simulating an external API call
        return webClient.get()
                .uri("http://external-service.com/api")
                .retrieve()
                .bodyToMono(String.class)
                .block();
    }

    public String fallbackResponse(Throwable t) {
        return "Service is unavailable, please try again later.";
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Prevent Overload with Throttling
&lt;/h2&gt;

&lt;p&gt;Imagine your app gets flooded with requests—maybe because you went viral, or someone’s intentionally hitting your endpoints nonstop. Without some kind of control, your servers could get overwhelmed, leading to crashes or performance issues.&lt;/p&gt;

&lt;p&gt;That’s where throttling comes in. It limits how often users (or systems) can access your app, helping you protect your backend and keep things running smoothly.&lt;/p&gt;

&lt;h3&gt;
  
  
  What’s Throttling?
&lt;/h3&gt;

&lt;p&gt;Throttling is like placing a speed limit on a highway. It ensures no one can send too many requests at once, giving your app breathing room to handle other users.&lt;/p&gt;

&lt;h3&gt;
  
  
  When Should You Use Throttling?
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;When your app serves a public API or has user-facing endpoints that could get spammed.&lt;/li&gt;
&lt;li&gt;To prevent abuse from automated bots or malicious users.&lt;/li&gt;
&lt;li&gt;To handle traffic surges gracefully, especially during sales or promotions.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  How to Implement Throttling in Spring Boot
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Option 1: Use Spring Web Filters for Simple Throttling
&lt;/h4&gt;

&lt;p&gt;For basic throttling, you can use a filter to track request counts and delay or block users who exceed the limit.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Component  
public class ThrottleFilter implements Filter {  

    private final Map&amp;lt;String, Integer&amp;gt; requestCounts = new ConcurrentHashMap&amp;lt;&amp;gt;();  
    private final int MAX_REQUESTS_PER_MINUTE = 100;  

    @Override  
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {  
        HttpServletRequest httpRequest = (HttpServletRequest) request;  
        String clientIP = httpRequest.getRemoteAddr();  

        requestCounts.merge(clientIP, 1, Integer::sum);  

        if (requestCounts.get(clientIP) &amp;gt; MAX_REQUESTS_PER_MINUTE) {  
            ((HttpServletResponse) response).setStatus(HttpServletResponse.SC_TOO_MANY_REQUESTS);  
            response.getWriter().write("Too many requests. Please try again later.");  
            return;  
        }  

        chain.doFilter(request, response);  
    }  

    @Scheduled(fixedRate = 60000)  
    public void resetCounts() {  
        requestCounts.clear();  
    }  
}  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This example tracks requests per client IP and blocks further requests if they exceed a set limit within a minute.&lt;/p&gt;

&lt;h4&gt;
  
  
  Option 2: Use a Library Like Bucket4j for Advanced Throttling
&lt;/h4&gt;

&lt;p&gt;For more control, such as rate-limiting based on API keys or user roles, use Bucket4j.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Add Dependency&lt;/strong&gt;&lt;br&gt;
Include the Bucket4j library:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;dependency&amp;gt;  
    &amp;lt;groupId&amp;gt;com.github.vladimir-bukhtoyarov&amp;lt;/groupId&amp;gt;  
    &amp;lt;artifactId&amp;gt;bucket4j-core&amp;lt;/artifactId&amp;gt;  
    &amp;lt;version&amp;gt;8.0.0&amp;lt;/version&amp;gt;  
&amp;lt;/dependency&amp;gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Set Up Throttling Logic&lt;/strong&gt;&lt;br&gt;
Here’s an example of rate-limiting requests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@RestController  
@RequestMapping("/api")  
public class RateLimitController {  

    private final Map&amp;lt;String, Bucket&amp;gt; buckets = new ConcurrentHashMap&amp;lt;&amp;gt;();  

    @GetMapping("/data")  
    public ResponseEntity&amp;lt;String&amp;gt; getData(HttpServletRequest request) {  
        String clientIP = request.getRemoteAddr();  
        Bucket bucket = buckets.computeIfAbsent(clientIP, k -&amp;gt; createNewBucket());  

        if (bucket.tryConsume(1)) {  
            return ResponseEntity.ok("Here's your data!");  
        } else {  
            return ResponseEntity.status(HttpStatus.TOO_MANY_REQUESTS).body("Rate limit exceeded. Try again later.");  
        }  
    }  

    private Bucket createNewBucket() {  
        return Bucket4j.builder()  
                .addLimit(Bandwidth.simple(50, Duration.ofMinutes(1)))  
                .build();  
    }  
}  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, each client can make 50 requests per minute. If they exceed the limit, they’ll get a &lt;code&gt;429 Too Many Requests&lt;/code&gt; response.&lt;/p&gt;

&lt;h4&gt;
  
  
  Option 3: Fine-Tune with Spring Cloud Gateway
&lt;/h4&gt;

&lt;p&gt;If you’re using a gateway, Spring Cloud Gateway makes it easy to add rate-limiting globally.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Add Dependencies&lt;/strong&gt;&lt;br&gt;
Include these in your &lt;code&gt;pom.xml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;dependency&amp;gt;  
    &amp;lt;groupId&amp;gt;org.springframework.cloud&amp;lt;/groupId&amp;gt;  
    &amp;lt;artifactId&amp;gt;spring-cloud-starter-gateway&amp;lt;/artifactId&amp;gt;  
&amp;lt;/dependency&amp;gt;  
&amp;lt;dependency&amp;gt;  
    &amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;  
    &amp;lt;artifactId&amp;gt;spring-boot-starter-data-redis&amp;lt;/artifactId&amp;gt;  
&amp;lt;/dependency&amp;gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Configure Rate-Limiting in &lt;code&gt;application.yml&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
Set up Redis-based rate-limiting for API routes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;spring:  
  cloud:  
    gateway:  
      routes:  
        - id: data-service  
          uri: http://localhost:8080  
          predicates:  
            - Path=/api/data  
          filters:  
            - name: RequestRateLimiter  
              args:  
                redis-rate-limiter:  
                  replenishRate: 10  
                  burstCapacity: 20  

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By adding throttling, you not only protect your system from abuse but also ensure a smoother experience for all users, even during traffic spikes.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Use Retry Strategies: Because Nobody Likes a Nag
&lt;/h2&gt;

&lt;p&gt;When dealing with temporary failures, retries can be a lifesaver, but overdoing them can overwhelm your system and make minor issues worse. It’s essential to implement retries thoughtfully to strike a balance between resilience and system stability.&lt;/p&gt;

&lt;h3&gt;
  
  
  Introducing Spring Retry
&lt;/h3&gt;

&lt;p&gt;Spring Retry is a powerful library that simplifies implementing retry mechanisms in Java applications. It integrates seamlessly with Spring, providing declarative and programmatic approaches to handle retries effectively.&lt;/p&gt;

&lt;p&gt;Spring Retry allows you to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Retry operations based on specific exceptions.&lt;/li&gt;
&lt;li&gt;Define policies like fixed intervals, exponential backoff, and more.&lt;/li&gt;
&lt;li&gt;Customize maximum retry attempts and delays.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Adding the Dependency
&lt;/h3&gt;

&lt;p&gt;To use Spring Retry in your project, add the following dependency to your &lt;code&gt;pom.xml&lt;/code&gt; :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.springframework.retry&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;spring-retry&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;1.3.4&amp;lt;/version&amp;gt; &amp;lt;!-- Use the latest version --&amp;gt;
&amp;lt;/dependency&amp;gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;spring-boot-starter-aop&amp;lt;/artifactId&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;spring-boot-starter-aop&lt;/code&gt; dependency is required for handling annotations like &lt;code&gt;@Retryable.&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Configuring Retry Logic
&lt;/h3&gt;

&lt;p&gt;Spring Retry provides annotations like &lt;code&gt;@Retryable&lt;/code&gt; to handle retries declaratively.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Enable Retry Support&lt;/strong&gt;: Add the &lt;code&gt;@EnableRetry&lt;/code&gt; annotation to your configuration class to enable retry functionality.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import org.springframework.context.annotation.Configuration;
import org.springframework.retry.annotation.EnableRetry;

@Configuration
@EnableRetry
public class RetryConfig {
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Add Retry Logic to a Service&lt;/strong&gt;: Use the @Retryable annotation to define retry policies.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import org.springframework.retry.annotation.Retryable;
import org.springframework.retry.annotation.Backoff;
import org.springframework.stereotype.Service;

@Service
public class ApiService {
    @Retryable(
        value = {RuntimeException.class},
        maxAttempts = 3,
        backoff = @Backoff(delay = 2000, multiplier = 2)
    )
    public String callExternalService() {
        System.out.println("Attempting to call external service...");
        throw new RuntimeException("Temporary failure");
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;value&lt;/code&gt;: Specifies the exceptions to trigger a retry.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;maxAttempts&lt;/code&gt;: Limits the number of retry attempts.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;backoff&lt;/code&gt;: Configures the delay between retries (e.g., exponential backoff with a multiplier).&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Fallback for Graceful Failure: Handle failures gracefully by defining a fallback method using &lt;code&gt;@Recover&lt;/code&gt;.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import org.springframework.retry.annotation.Recover;
import org.springframework.stereotype.Service;

@Service
public class ApiService {
    // Retryable method as shown above

    @Recover
    public String recover(RuntimeException e) {
        System.out.println("Fallback executed due to: " + e.getMessage());
        return "Fallback response";
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Bottom Line: Focus on Interactions
&lt;/h2&gt;

&lt;p&gt;A truly resilient system isn't just about robust services; it’s about ensuring those services interact seamlessly and effectively.&lt;/p&gt;

&lt;p&gt;By caching wisely, preventing cascading failures, designing fallbacks, and managing retries, you can create systems that effortlessly bounce back from issues.&lt;/p&gt;

&lt;p&gt;Failures are inevitable, but what truly defines a resilient system is how gracefully it responds to those challenges.&lt;/p&gt;

&lt;p&gt;Best of luck in building your resilient system, may it handle every hiccup like a pro!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Easily Set Up Multiple Spring Beans with Unique Configurations</title>
      <dc:creator>Thompson Olufemi</dc:creator>
      <pubDate>Tue, 29 Oct 2024 07:30:53 +0000</pubDate>
      <link>https://dev.to/thompsonolufemi/easily-set-up-multiple-spring-beans-with-unique-configurations-3df1</link>
      <guid>https://dev.to/thompsonolufemi/easily-set-up-multiple-spring-beans-with-unique-configurations-3df1</guid>
      <description>&lt;p&gt;&lt;strong&gt;Tired of Repetitive Spring Bean Registrations? You’re Not Alone!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ever feel bogged down with repeated bean definitions in Spring Boot? You’re not alone! Managing multiple beans of the same class with different configurations can get tedious and cluttered. Let's say you need something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Bean
MyService beanA() {
    // Set Configuration for bean A
    Configuration a = new...
    a.setUrl(.....)
    return new MyService(a);
}

@Bean
MyService beanB() {
    // Set Configuration for bean A
    Configuration b = new...
    b.setUrl(.....)
    return new MyService(b);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code isn't complex, but it quickly becomes repetitive, especially when dealing with several beans of the same type. Ideally, you'd have a way to register multiple instances with distinct settings without redundant code.&lt;/p&gt;

&lt;p&gt;This differs from having unique beans for each implementation of an interface. Instead, we’re talking about setting up one class with variations. For example, think of an app that connects to multiple databases (e.g., customer, reporting, and backup). Each connection needs its own configuration, making it challenging to manage without clutter. You might end up writing something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Bean
DatabaseService primaryDatabaseService() {
    return new DatabaseService("db-url-primary");
}

@Bean
DatabaseService reportDatabaseService() {
    return new DatabaseService("db-url-report");
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Having a simpler solution could significantly streamline your configuration and let you focus more on application logic. Enter &lt;a href="https://github.com/olufemithompson/multibeanconfig" rel="noopener noreferrer"&gt;MultiBeanConfig&lt;/a&gt; — a small library I built to help manage multiple configurations for the same Spring bean.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing MultiBeanConfig
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/olufemithompson/multibeanconfig" rel="noopener noreferrer"&gt;MultiBeanConfig&lt;/a&gt; simplifies the setup of multiple instances of a bean with separate configurations. With it, you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reduce repetitive code&lt;/li&gt;
&lt;li&gt;Centralize configuration management&lt;/li&gt;
&lt;li&gt;Keep your codebase clean and organized&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Core Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Multiple Bean Setup&lt;/strong&gt;: Define multiple instances of a single class.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custom Configurations&lt;/strong&gt;: Control settings per instance through your application properties.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Default Values&lt;/strong&gt;: Automatically apply default values if specific configurations are missing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automatic Injection&lt;/strong&gt;: Easily use &lt;code&gt;@Autowired&lt;/code&gt; for dependency injection.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step-by-Step Guide
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Add MultiBeanConfig to Your Project
&lt;/h3&gt;

&lt;p&gt;Include the dependency in your pom.xml:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;io.github.olufemithompson&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;multibeanconfig&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;0.0.3&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Set Up the Bean Class
&lt;/h3&gt;

&lt;p&gt;Mark your class with &lt;code&gt;@MultiBean&lt;/code&gt; to make it eligible for multiple instances:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@MultiBean
public class DatabaseService {
    // Your service logic
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Define Beans in Your Config File
&lt;/h3&gt;

&lt;p&gt;Define unique versions in your properties or YAML file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;multibean:
  primary-database-service:
    class: DatabaseService
  report-database-service:
    class: DatabaseService
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This registers &lt;code&gt;primaryDatabaseService&lt;/code&gt; and &lt;code&gt;reportDatabaseService&lt;/code&gt; beans with default configurations. &lt;a href="https://github.com/olufemithompson/multibeanconfig" rel="noopener noreferrer"&gt;MultiBeanConfig&lt;/a&gt;  automatically translates names from kebab-case to camelCase.&lt;/p&gt;

&lt;h2&gt;
  
  
  Customizing Configurations Per Bean
&lt;/h2&gt;

&lt;p&gt;To assign separate settings, add properties directly to each bean’s configuration. Here’s an example where each instance connects to a different database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@MultiBean
public class DatabaseService {
   @Value("${database-config.connection-url}")
   private String connectionUrl;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Configure each instance in application.yml:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;database-config:
  connection-url: 'jdbc:h2:default-url'

multibean:
  primary-database-service:
    class: DatabaseService
    database-config:
      connection-url: 'jdbc:mysql:primary-db-url'
  report-database-service:
    class: DatabaseService
    database-config:
      connection-url: 'jdbc:postgresql:report-db-url'

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This setup gives each bean a unique connection URL. Shared settings can also be defined in a general section, making configurations efficient and reducing redundancy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Alternative Ways to Inject Configurations
&lt;/h2&gt;

&lt;p&gt;You don’t have to rely solely on &lt;code&gt;@Value&lt;/code&gt; for injecting configurations. Spring’s &lt;code&gt;@ConfigurationProperties&lt;/code&gt; allows encapsulating properties in a configuration class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@ConfigurationProperties("database-config")
@Configuration
public class DatabaseConfig {
    private String connectionUrl;
    private int connectionTimeout;
    // Getters and Setters
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, inject &lt;code&gt;DatabaseConfig&lt;/code&gt; directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@MultiBean
public class DatabaseService {
   private final DatabaseConfig databaseConfig;
   public DatabaseService(DatabaseConfig databaseConfig) {
       this.databaseConfig = databaseConfig;
   }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Using the Configured Beans
&lt;/h2&gt;

&lt;p&gt;With &lt;a href="https://github.com/olufemithompson/multibeanconfig" rel="noopener noreferrer"&gt;MultiBeanConfig&lt;/a&gt; , inject your uniquely configured beans as you would with any Spring dependency:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Service
public class ApplicationService {
   private final DatabaseService primaryDatabaseService;
   private final DatabaseService reportDatabaseService;

   public ApplicationService(DatabaseService primaryDatabaseService, DatabaseService reportDatabaseService) {
       this.primaryDatabaseService = primaryDatabaseService;
       this.reportDatabaseService = reportDatabaseService;
   }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/olufemithompson/multibeanconfig" rel="noopener noreferrer"&gt;MultiBeanConfig&lt;/a&gt;  streamlines bean management in Spring Boot applications, especially when handling feature flags, data sources, or distinct API connections. It reduces redundancy, keeps your code clean, and enhances maintainability. Give it a try, and let me know how it works for your projects!&lt;/p&gt;

</description>
      <category>spring</category>
      <category>java</category>
      <category>springboot</category>
      <category>dependencyinjection</category>
    </item>
  </channel>
</rss>
