<feed xmlns="http://www.w3.org/2005/Atom"> <id>https://dmitrii-russu.github.io/</id><title>Dmitrii Russu</title><subtitle>Technical blog about backend architecture, persistence, and domain-driven design.</subtitle> <updated>2026-09-28T16:34:57+03:00</updated> <author> <name>Dmitrii Russu</name> <uri>https://dmitrii-russu.github.io/</uri> </author><link rel="self" type="application/atom+xml" href="https://dmitrii-russu.github.io/feed.xml"/><link rel="alternate" type="text/html" hreflang="en" href="https://dmitrii-russu.github.io/"/> <generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator> <rights> © 2026 Dmitrii Russu </rights> <icon>/assets/img/favicons/favicon.ico</icon> <logo>/assets/img/favicons/favicon-96x96.png</logo> <entry><title>Where Domain Roles Should Live: The Boundary Between the Authorization Server and the Resource Server</title><link href="https://dmitrii-russu.github.io/posts/authorization-domain-roles/" rel="alternate" type="text/html" title="Where Domain Roles Should Live: The Boundary Between the Authorization Server and the Resource Server" /><published>2026-09-28T08:00:00+03:00</published> <updated>2026-09-28T16:34:38+03:00</updated> <id>https://dmitrii-russu.github.io/posts/authorization-domain-roles/</id> <content type="text/html" src="https://dmitrii-russu.github.io/posts/authorization-domain-roles/" /> <author> <name>Dmitrii Russu</name> </author> <category term="Architecture" /> <category term="Backend" /> <summary>In short: domain roles belong where the domain lives. Putting them on the auth server couples it to someone else’s business model, and baking them into the JWT freezes them for the lifetime of the token. Mapping the token’s identity to a domain user on the resource server keeps the boundary clean and puts you in control of how fast a revoked role takes effect. Your resource server needs a user...</summary> </entry> <entry><title>Constraint Violations: Why the Database Still Gets the Final Say</title><link href="https://dmitrii-russu.github.io/posts/constraint-violations/" rel="alternate" type="text/html" title="Constraint Violations: Why the Database Still Gets the Final Say" /><published>2026-09-25T08:00:00+03:00</published> <updated>2026-09-25T10:41:17+03:00</updated> <id>https://dmitrii-russu.github.io/posts/constraint-violations/</id> <content type="text/html" src="https://dmitrii-russu.github.io/posts/constraint-violations/" /> <author> <name>Dmitrii Russu</name> </author> <category term="Architecture" /> <category term="Backend" /> <summary>In short: input validation is a filter, not a guarantee. It rejects malformed requests before they cost you anything, but it can’t see what’s already in the table. Uniqueness and integrity are facts about storage state, and only storage can enforce them — which means the database ends up checking some of the same things your code already checked, on purpose. You insert a customer with an email...</summary> </entry> <entry><title>Idempotency: Why a Repeated Click Can Cost a Business Money</title><link href="https://dmitrii-russu.github.io/posts/idempotency/" rel="alternate" type="text/html" title="Idempotency: Why a Repeated Click Can Cost a Business Money" /><published>2026-08-31T08:00:00+03:00</published> <updated>2026-09-01T09:48:31+03:00</updated> <id>https://dmitrii-russu.github.io/posts/idempotency/</id> <content type="text/html" src="https://dmitrii-russu.github.io/posts/idempotency/" /> <author> <name>Dmitrii Russu</name> </author> <category term="Architecture" /> <category term="Backend" /> <summary>In short: idempotency isn’t about rejecting duplicate requests — it’s about making sure the same intent, delivered more than once, never triggers the side effect a second time. A retry after a dropped connection and a brand-new order look identical on the wire, but only the server can tell them apart — and only if it captures intent, not just input. Idempotency of an operation means that execu...</summary> </entry> <entry><title>Cache as a Pre-Filter Before a Database Constraint</title><link href="https://dmitrii-russu.github.io/posts/cache-pre-filter/" rel="alternate" type="text/html" title="Cache as a Pre-Filter Before a Database Constraint" /><published>2026-08-20T08:00:00+03:00</published> <updated>2026-08-20T11:58:54+03:00</updated> <id>https://dmitrii-russu.github.io/posts/cache-pre-filter/</id> <content type="text/html" src="https://dmitrii-russu.github.io/posts/cache-pre-filter/" /> <author> <name>Dmitrii Russu</name> </author> <category term="Architecture" /> <category term="Caching" /> <summary>In short: a cache can decide the outcome of an operation before the database is ever asked. Checking a cache before a write looks like a pure performance trick — skip the redundant query, save a round-trip. But a cache hit doesn’t just skip the database, it replaces its decision. The database constraint always guarantees data integrity. But a cache hit can decide success or rejection on its own...</summary> </entry> <entry><title>"Grouping SQL Queries" Is Not a Transaction Boundary. Here's the Real Criterion</title><link href="https://dmitrii-russu.github.io/posts/transaction-boundary-criterion/" rel="alternate" type="text/html" title="&amp;quot;Grouping SQL Queries&amp;quot; Is Not a Transaction Boundary. Here&amp;apos;s the Real Criterion" /><published>2026-08-13T13:00:00+03:00</published> <updated>2026-08-13T17:27:50+03:00</updated> <id>https://dmitrii-russu.github.io/posts/transaction-boundary-criterion/</id> <content type="text/html" src="https://dmitrii-russu.github.io/posts/transaction-boundary-criterion/" /> <author> <name>Dmitrii Russu</name> </author> <category term="Architecture" /> <category term="Transactions" /> <summary>In short: a transaction boundary isn’t determined by which SQL queries physically execute together, but by which component knows about the business invariant that ties multiple repository calls together. In data-centric code these two things coincide — which is why the classic examples become confusing the moment a layered architecture appears: the repository stops being the place where busines...</summary> </entry> </feed>
