<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>Tech Cafe - backend</title>
    <subtitle>Dev adventures, epic bugs, tiny wins, and the occasional meltdown.</subtitle>
    <link rel="self" type="application/atom+xml" href="https://golden-fox.dev/tags/backend/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://golden-fox.dev"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-06-17T00:00:00+00:00</updated>
    <id>https://golden-fox.dev/tags/backend/atom.xml</id>
    <entry xml:lang="en">
        <title>mini-api-gateway</title>
        <published>2026-06-17T00:00:00+00:00</published>
        <updated>2026-06-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Aakriti Agarwal
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://golden-fox.dev/projects/mini-api-gateway/"/>
        <id>https://golden-fox.dev/projects/mini-api-gateway/</id>
        
        <content type="html" xml:base="https://golden-fox.dev/projects/mini-api-gateway/">&lt;p&gt;An API gateway sits in front of your services doing the unglamorous work: checking who is
calling, deciding whether they are allowed through, then passing the request along. I kept
seeing the term without really knowing what was inside one, so I built a small one.&lt;&#x2F;p&gt;
&lt;p&gt;A request to &lt;code&gt;&#x2F;proxy&lt;&#x2F;code&gt; hits a filter that reads the &lt;code&gt;x-api-key&lt;&#x2F;code&gt; header and asks a rate
limiter whether this caller has any budget left. The limiter keeps a counter in Redis
against that key, set to expire after 60 seconds, so five requests a minute get through
and the sixth gets a 429. Anything that survives the filter is forwarded upstream.&lt;&#x2F;p&gt;
&lt;p&gt;Letting Redis do the remembering was the part that clicked. A counter that expires on its
own is a far simpler thing to reason about than one you have to remember to clean up, and
the sliding window falls out of the expiry for free.&lt;&#x2F;p&gt;
&lt;p&gt;Still small. One route, one upstream. Next up is validating the key properly rather than
only rate limiting on it, plus an atomic counter so concurrent requests cannot slip past
the window.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Built with:&lt;&#x2F;strong&gt; Java 21, Spring Boot, Redis, Maven&lt;&#x2F;p&gt;
</content>
        
    </entry>
</feed>
