---
title: "Leo D. Penrose (@ldpenrose) | Hashnode"
description: "Leo D. Penrose (@ldpenrose) writes on Hashnode. Read their latest articles and follow their work."
url: "https://hashnode.com/@ldpenrose"
---

@ldpenrose

# Leo D. Penrose

@ldpenrose · Joined August 2019

### [Closing the Loop: Proxy-Aware Rate Limiting With X-Forwarded-For](https://buildingbibby.hashnode.dev/closing-the-loop-proxy-aware-rate-limiting-with-x-forwarded-for?utm_source=hashnode&utm_medium=feed)

TL;DR The previous PR fixed getLocalAddr() → getRemoteAddr() for rate limiting. That fix is still broken behind a reverse proxy: getRemoteAddr() returns the proxy's IP, so all real clients share one

5 min read · [buildingbibby.hashnode.dev](https://buildingbibby.hashnode.dev/closing-the-loop-proxy-aware-rate-limiting-with-x-forwarded-for?utm_source=hashnode&utm_medium=feed)

[1](https://hashnode.com/posts/closing-the-loop-proxy-aware-rate-limiting-with-x-forwarded-for/69aa6e5be2698e32064d9a80) [Mar 6](https://hashnode.com/posts/closing-the-loop-proxy-aware-rate-limiting-with-x-forwarded-for/69aa6e5be2698e32064d9a80)

### [Token Buckets, API Keys, and the Bug That Rate-Limited the Server](https://buildingbibby.hashnode.dev/token-buckets-api-keys-and-the-bug-that-rate-limited-the-server?utm_source=hashnode&utm_medium=feed)

TL;DR The /api/v1/books/fetchbookmetadata endpoint had no abuse protection. Any client could spam ISBN lookups indefinitely, exhausting Google Books anonymous quota for every user. Implemented a han

11 min read · [buildingbibby.hashnode.dev](https://buildingbibby.hashnode.dev/token-buckets-api-keys-and-the-bug-that-rate-limited-the-server?utm_source=hashnode&utm_medium=feed)

[Mar 6](https://hashnode.com/posts/token-buckets-api-keys-and-the-bug-that-rate-limited-the-server/69aa5b11b8d41e6dedfa13da)

### [How I Enforced Hexagonal Boundaries Across 92 Commits in One Week](https://buildingbibby.hashnode.dev/how-i-enforced-hexagonal-boundaries-across-92-commits-in-one-week?utm_source=hashnode&utm_medium=feed)

When I ran IntelliJ's Dependency Structure Matrix on Bibby — my personal library management system built with Spring Boot and DDD — the result was ugly. My BookController was reaching directly into Sh

7 min read · [buildingbibby.hashnode.dev](https://buildingbibby.hashnode.dev/how-i-enforced-hexagonal-boundaries-across-92-commits-in-one-week?utm_source=hashnode&utm_medium=feed)

[Mar 2](https://hashnode.com/posts/how-i-enforced-hexagonal-boundaries-across-92-commits-in-one-week/69a5f4dfe8e1f9df72e50dc7)

### [Hollowing Out a Facade: Completing the Use Case Port Extraction](https://buildingbibby.hashnode.dev/hollowing-out-a-facade-completing-the-use-case-port-extraction?utm_source=hashnode&utm_medium=feed)

TL;DR ShelfCommandFacade had three methods. All three now have dedicated single-method ports. The facade is dead code. PlaceBookOnShelfUseCasePort extracted: BookController and ShelfController now i

10 min read · [buildingbibby.hashnode.dev](https://buildingbibby.hashnode.dev/hollowing-out-a-facade-completing-the-use-case-port-extraction?utm_source=hashnode&utm_medium=feed)

[Mar 2](https://hashnode.com/posts/hollowing-out-a-facade-completing-the-use-case-port-extraction/69a5dfbae8e1f9df72d718e5)

### [One Method Is Enough: Extracting a Use Case Port for Cross-Module Deletion](https://buildingbibby.hashnode.dev/one-method-is-enough-extracting-a-use-case-port-for-cross-module-deletion?utm_source=hashnode&utm_medium=feed)

TL;DR ShelfAccessPortAdapter (in the bookcase module) needed to delete shelves. It did this through ShelfCommandFacade — a 3-method interface whose other two methods the adapter never touches. Fix:

10 min read · [buildingbibby.hashnode.dev](https://buildingbibby.hashnode.dev/one-method-is-enough-extracting-a-use-case-port-for-cross-module-deletion?utm_source=hashnode&utm_medium=feed)

[Mar 2](https://hashnode.com/posts/one-method-is-enough-extracting-a-use-case-port-for-cross-module-deletion/69a4e1e3a7428b958d067608)
