<?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>Forem: umesh kushwaha</title>
    <description>The latest articles on Forem by umesh kushwaha (@umesh_kushwaha_6655ba4c0d).</description>
    <link>https://forem.com/umesh_kushwaha_6655ba4c0d</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%2F1838419%2F6781ec86-5f12-40d1-b9d3-09ef0c0c735d.png</url>
      <title>Forem: umesh kushwaha</title>
      <link>https://forem.com/umesh_kushwaha_6655ba4c0d</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/umesh_kushwaha_6655ba4c0d"/>
    <language>en</language>
    <item>
      <title>🚀 Designing a Flash Sale System That Never Oversells&lt;/h1&gt; &lt;h3&gt;From 1 User to 1 Million Users (Without Crashing Redis)</title>
      <dc:creator>umesh kushwaha</dc:creator>
      <pubDate>Fri, 06 Feb 2026 07:19:05 +0000</pubDate>
      <link>https://forem.com/umesh_kushwaha_6655ba4c0d/designing-a-flash-sale-system-that-never-oversells-from-1-user-to-1-million-users-3fih</link>
      <guid>https://forem.com/umesh_kushwaha_6655ba4c0d/designing-a-flash-sale-system-that-never-oversells-from-1-user-to-1-million-users-3fih</guid>
      <description>&lt;p&gt;&lt;em&gt;Example: Flash sale for &lt;strong&gt;1,000 iPhones&lt;/strong&gt; with &lt;strong&gt;1,000,000 users&lt;/strong&gt; clicking “Buy” at the same time.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;🧠 Why Flash Sales Are Hard&lt;/h2&gt;

&lt;p&gt;Flash sales look simple:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“We have 1,000 items. When inventory reaches zero, stop selling.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But in production, flash sales are one of the &lt;strong&gt;hardest problems in distributed systems&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Millions of concurrent requests&lt;/li&gt;
  &lt;li&gt;Multiple app servers&lt;/li&gt;
  &lt;li&gt;Eventually consistent caches&lt;/li&gt;
  &lt;li&gt;Databases that cannot absorb spikes&lt;/li&gt;
  &lt;li&gt;Redis that can still melt under pressure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The real challenge is not inventory.&lt;/strong&gt;&lt;br&gt;
It is &lt;strong&gt;correctness under extreme contention&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;🎯 Core Requirements&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;❌ No overselling (ever)&lt;/li&gt;
  &lt;li&gt;⚡ Low latency&lt;/li&gt;
  &lt;li&gt;🧱 Handle massive traffic spikes&lt;/li&gt;
  &lt;li&gt;🔥 Protect Redis &amp;amp; database&lt;/li&gt;
  &lt;li&gt;🛡️ Graceful failure &amp;amp; recovery&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;🧩 Core Insight&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;Flash sales are load-shedding problems disguised as inventory problems.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If only &lt;strong&gt;1,000 users can succeed&lt;/strong&gt;, then &lt;strong&gt;999,000 users must fail fast&lt;/strong&gt; — cheaply and safely.&lt;/p&gt;




&lt;h2&gt;1️⃣ Naive Database Approach (Incorrect)&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;SELECT stock FROM inventory WHERE product_id = 1;

IF stock &amp;gt; 0:
  UPDATE inventory SET stock = stock - 1;
  CREATE order;&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;❌ What goes wrong&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Two requests read stock = 1&lt;/li&gt;
  &lt;li&gt;Both decrement&lt;/li&gt;
  &lt;li&gt;Inventory oversold&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Verdict:&lt;/strong&gt; ❌ Incorrect even at low scale.&lt;/p&gt;




&lt;h2&gt;2️⃣ Database Locking (Correct but Not Scalable)&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;SELECT stock
FROM inventory
WHERE product_id = 1
FOR UPDATE;&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;✅ Pros&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Strong consistency&lt;/li&gt;
  &lt;li&gt;No overselling&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;❌ Cons&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Requests serialized&lt;/li&gt;
  &lt;li&gt;Database becomes bottleneck&lt;/li&gt;
  &lt;li&gt;Throughput collapses&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Use only for very low traffic.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;3️⃣ Atomic SQL Update (Better, Still Limited)&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;UPDATE inventory
SET stock = stock - 1
WHERE product_id = 1 AND stock &amp;gt; 0;&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;✅ Pros&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Simple&lt;/li&gt;
  &lt;li&gt;Correct&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;❌ Cons&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Database still hot&lt;/li&gt;
  &lt;li&gt;Does not scale for flash sales&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;4️⃣ Redis as Inventory Gatekeeper&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;DECR inventory:iphone&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If result &amp;lt; 0 → rollback and reject.&lt;/p&gt;

&lt;h3&gt;Redis + Lua (Atomic)&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;local stock = redis.call("GET", KEYS[1])
if tonumber(stock) &amp;gt; 0 then
  redis.call("DECR", KEYS[1])
  return 1
else
  return 0
end&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;✅ Pros&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Very fast&lt;/li&gt;
  &lt;li&gt;No overselling&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;🚨 Hidden Problem: Redis Can Still Go Down&lt;/h2&gt;

&lt;p&gt;Scenario:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Inventory: 1,000&lt;/li&gt;
  &lt;li&gt;Users: 1,000,000&lt;/li&gt;
  &lt;li&gt;All users hit the same Redis key&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even Redis has limits:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Single hot shard&lt;/li&gt;
  &lt;li&gt;Network saturation&lt;/li&gt;
  &lt;li&gt;CPU contention&lt;/li&gt;
  &lt;li&gt;Timeouts and failures&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;Correctness without traffic control is failure.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;5️⃣ Mandatory Defense: Early Rejection&lt;/h2&gt;

&lt;h3&gt;Local In-Memory Gate&lt;/h3&gt;

&lt;p&gt;Each app instance keeps a small local counter.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;if localRemaining == 0:
  reject immediately&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;✅ Pros&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Protects Redis massively&lt;/li&gt;
  &lt;li&gt;Very cheap&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;❌ Cons&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Soft limits&lt;/li&gt;
  &lt;li&gt;Needs reconciliation&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;6️⃣ Batch Inventory Allocation (High Impact)&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;DECRBY inventory:iphone 20&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Serve 20 users locally before hitting Redis again.&lt;/p&gt;

&lt;h3&gt;✅ Pros&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Redis calls ≈ inventory count&lt;/li&gt;
  &lt;li&gt;Huge throughput improvement&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;❌ Cons&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Over-allocation needs give-back logic&lt;/li&gt;
  &lt;li&gt;Slight fairness skew&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;7️⃣ Redis Hot Shard Problem &amp;amp; Striping&lt;/h2&gt;

&lt;p&gt;Single key → single shard → overload.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Bucketed inventory.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;inv:iphone:0
inv:iphone:1
...
inv:iphone:49&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;✅ Pros&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Load distributed across shards&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;❌ Cons&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Retry logic near tail&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;8️⃣ Token / Permit Model&lt;/h2&gt;

&lt;p&gt;1 token = 1 purchase. Pre-generate 1,000 tokens.&lt;/p&gt;

&lt;h3&gt;✅ Pros&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Impossible to oversell&lt;/li&gt;
  &lt;li&gt;Clean mental model&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;❌ Cons&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Token cleanup on failure&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;9️⃣ Admission Control&lt;/h2&gt;

&lt;p&gt;Only allow slightly more users than inventory to proceed.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;INCR sale:attempts
reject if &amp;gt; 1500&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Effect&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Redis protected&lt;/li&gt;
  &lt;li&gt;Fast rejection&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;🔟 Queue-Based Flash Sale (Extreme Scale)&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Users enqueue buy requests&lt;/li&gt;
  &lt;li&gt;Workers process sequentially&lt;/li&gt;
  &lt;li&gt;Stop after inventory exhausted&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Trade-off&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Higher latency&lt;/li&gt;
  &lt;li&gt;Excellent stability&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;🔄 Failure Handling&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;
&lt;strong&gt;Payment failure:&lt;/strong&gt; TTL + release inventory&lt;/li&gt;
  &lt;li&gt;
&lt;strong&gt;Duplicate clicks:&lt;/strong&gt; Idempotency keys&lt;/li&gt;
  &lt;li&gt;
&lt;strong&gt;Redis crash:&lt;/strong&gt; Reload from DB&lt;/li&gt;
  &lt;li&gt;
&lt;strong&gt;Cache drift:&lt;/strong&gt; Reconciliation job&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;⚖️ Trade-off Summary&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;tr&gt;
    &lt;th&gt;Approach&lt;/th&gt;
    &lt;th&gt;Scale&lt;/th&gt;
    &lt;th&gt;Redis Load&lt;/th&gt;
    &lt;th&gt;Complexity&lt;/th&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;DB Lock&lt;/td&gt;
    &lt;td&gt;Low&lt;/td&gt;
    &lt;td&gt;None&lt;/td&gt;
    &lt;td&gt;Low&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Redis DECR&lt;/td&gt;
    &lt;td&gt;High&lt;/td&gt;
    &lt;td&gt;High&lt;/td&gt;
    &lt;td&gt;Medium&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Batch Allocation&lt;/td&gt;
    &lt;td&gt;Very High&lt;/td&gt;
    &lt;td&gt;Low&lt;/td&gt;
    &lt;td&gt;High&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Queue-Based&lt;/td&gt;
    &lt;td&gt;Extreme&lt;/td&gt;
    &lt;td&gt;Minimal&lt;/td&gt;
    &lt;td&gt;High&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;🏁 Final Thought&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;A successful flash sale is not about selling fast.&lt;br&gt;
  It is about &lt;strong&gt;rejecting users correctly&lt;/strong&gt; while protecting shared state.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;If you enjoyed this, follow for more system design deep dives.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>systemdesign</category>
      <category>distributedsystems</category>
      <category>designsystem</category>
      <category>microservices</category>
    </item>
    <item>
      <title>🚀 How Uber, Swiggy &amp; Zomato Find the Nearest Delivery Agent in Real Time</title>
      <dc:creator>umesh kushwaha</dc:creator>
      <pubDate>Fri, 23 Jan 2026 13:20:22 +0000</pubDate>
      <link>https://forem.com/umesh_kushwaha_6655ba4c0d/how-uber-swiggy-zomato-find-the-nearest-delivery-agent-in-real-time-2jgi</link>
      <guid>https://forem.com/umesh_kushwaha_6655ba4c0d/how-uber-swiggy-zomato-find-the-nearest-delivery-agent-in-real-time-2jgi</guid>
      <description>&lt;h2&gt;Real-Time Matching Architecture Using Redis (Deep Dive)&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Finding nearby restaurants is a search problem. Finding a nearby delivery agent is a real-time coordination problem.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This blog focuses on how large-scale systems match a restaurant or user with the &lt;strong&gt;nearest available delivery agent&lt;/strong&gt; in &lt;strong&gt;near real time&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;1️⃣ Problem Definition&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Inputs&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Pickup location (restaurant or user)&lt;/li&gt;
  &lt;li&gt;Thousands of moving agents&lt;/li&gt;
  &lt;li&gt;Agent state: available, assigned, offline&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Exactly one agent assigned&lt;/li&gt;
  &lt;li&gt;Low ETA&lt;/li&gt;
  &lt;li&gt;&amp;lt; 100ms decision time&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;2️⃣ Data Characteristics (Why Search Systems Fail Here)&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Attribute&lt;/th&gt;
      &lt;th&gt;Behavior&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
&lt;td&gt;Location&lt;/td&gt;
&lt;td&gt;Updates every 2–5 seconds&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
&lt;td&gt;Availability&lt;/td&gt;
&lt;td&gt;Highly volatile&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
&lt;td&gt;Write throughput&lt;/td&gt;
&lt;td&gt;Extremely high&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
&lt;td&gt;Consistency&lt;/td&gt;
&lt;td&gt;Near real-time&lt;/td&gt;
&lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;➡️ This is &lt;strong&gt;not a search problem&lt;/strong&gt;&lt;br&gt;
➡️ This is a &lt;strong&gt;real-time in-memory coordination problem&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;3️⃣ High-Level Architecture&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;
Agent App → Location Updates → Redis (Geo Index)
                                 ↓
Order Created → Matching Service → Availability Filter
                                 ↓
                          Assignment Lock
                                 ↓
                         Notification Service
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; Location, availability, and assignment are &lt;em&gt;separate concerns&lt;/em&gt;.&lt;/p&gt;




&lt;h2&gt;4️⃣ Core Redis Data Structures&lt;/h2&gt;

&lt;h3&gt;1. Location Index (Geo / Geohash)&lt;/h3&gt;

&lt;p&gt;Stores only &lt;strong&gt;where agents are&lt;/strong&gt;, nothing else.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
GEOADD drivers:geo:blr 77.5946 12.9716 driver_123
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This structure answers one question:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“Who is physically nearby?”&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;2. Availability Set (Separate)&lt;/h3&gt;

&lt;p&gt;Availability is volatile and must &lt;strong&gt;not&lt;/strong&gt; be embedded in geo keys.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
SADD drivers:available:blr driver_123
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This answers:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“Who is eligible to receive an order?”&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;3. Assignment Lock (Separate)&lt;/h3&gt;

&lt;p&gt;Assignment is transient and must be atomic.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
SET agent:123:lock order_789 NX EX 10
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This ensures:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“No agent is assigned twice.”&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;5️⃣ Why Availability Must NOT Be Stored with GeoHash&lt;/h2&gt;

&lt;p&gt;Embedding availability inside geo keys causes serious problems.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Geo + Availability Combined&lt;/th&gt;
      &lt;th&gt;Separated Structures&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
&lt;td&gt;Frequent reindexing&lt;/td&gt;
&lt;td&gt;Stable geo index&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
&lt;td&gt;High write amplification&lt;/td&gt;
&lt;td&gt;Cheap set updates&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
&lt;td&gt;Complex cleanup&lt;/td&gt;
&lt;td&gt;Simple TTL / set ops&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
&lt;td&gt;Poor scalability&lt;/td&gt;
&lt;td&gt;Horizontal scaling&lt;/td&gt;
&lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Rule of thumb:&lt;/strong&gt;&lt;br&gt;
📍 Geo index answers &lt;em&gt;where&lt;/em&gt;&lt;br&gt;
✅ Availability answers &lt;em&gt;who&lt;/em&gt;&lt;br&gt;
🔒 Lock answers &lt;em&gt;who wins&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;6️⃣ Spatial Segmentation (Preprocessing)&lt;/h2&gt;

&lt;p&gt;To avoid hot keys and large scans, systems segment the map.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
geo_cell = geohash(lat, lon, precision=7)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Data layout:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
drivers:geo:cell:tdr9k
drivers:available:cell:tdr9k
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Each cell is independent and scalable.&lt;/p&gt;




&lt;h2&gt;7️⃣ Matching Flow (Step-by-Step)&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;Identify pickup geo cell&lt;/li&gt;
  &lt;li&gt;Fetch nearby agent IDs from GEO index&lt;/li&gt;
  &lt;li&gt;Intersect with availability set&lt;/li&gt;
  &lt;li&gt;Sort by ETA / distance&lt;/li&gt;
  &lt;li&gt;Attempt assignment via lock&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Intersection example:&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
nearby_agents = GEORADIUS(...)
available_agents = SMEMBERS(...)
candidates = intersection(nearby_agents, available_agents)
&lt;/code&gt;&lt;/pre&gt;




&lt;h2&gt;8️⃣ Sequential Assignment (Preferred Strategy)&lt;/h2&gt;

&lt;p&gt;Most delivery platforms use sequential assignment.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
for agent in candidates:
    if acquire_lock(agent):
        send_request(agent)
        wait T seconds
        if accepted:
            assign
            break
        else:
            release_lock(agent)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This minimizes agent spam and improves acceptance quality.&lt;/p&gt;




&lt;h2&gt;9️⃣ Handling Rejections &amp;amp; Timeouts&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Timeout → agent returned to availability set&lt;/li&gt;
  &lt;li&gt;Reject → next best candidate&lt;/li&gt;
  &lt;li&gt;No response → TTL auto-release&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Redis TTLs prevent stuck assignments.&lt;/p&gt;




&lt;h2&gt;🔟 Write Amplification Control&lt;/h2&gt;

&lt;p&gt;Agents update location frequently. Mitigations include:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Update only if moved &amp;gt; X meters&lt;/li&gt;
  &lt;li&gt;Adaptive frequency (slow vs fast movement)&lt;/li&gt;
  &lt;li&gt;Batch updates&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Availability changes are &lt;strong&gt;cheap set operations&lt;/strong&gt;, not geo rewrites.&lt;/p&gt;




&lt;h2&gt;1️⃣1️⃣ Failure Handling&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Failure&lt;/th&gt;
      &lt;th&gt;Mitigation&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
&lt;td&gt;Agent crash&lt;/td&gt;
&lt;td&gt;TTL expiry&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
&lt;td&gt;Redis node down&lt;/td&gt;
&lt;td&gt;Sharding + replicas&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
&lt;td&gt;Network lag&lt;/td&gt;
&lt;td&gt;Optimistic retries&lt;/td&gt;
&lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;1️⃣2️⃣ Why Elasticsearch Is the Wrong Tool Here&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Elasticsearch&lt;/th&gt;
      &lt;th&gt;Redis&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
&lt;td&gt;Index refresh latency&lt;/td&gt;
&lt;td&gt;Instant mutation&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
&lt;td&gt;Disk-based&lt;/td&gt;
&lt;td&gt;In-memory&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
&lt;td&gt;Search optimized&lt;/td&gt;
&lt;td&gt;Coordination optimized&lt;/td&gt;
&lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Real-time assignment requires Redis.&lt;/p&gt;




&lt;h2&gt;1️⃣3️⃣ Key Tradeoffs&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Decision&lt;/th&gt;
      &lt;th&gt;Tradeoff&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
&lt;td&gt;Separate availability&lt;/td&gt;
&lt;td&gt;Extra lookup, massive scalability&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
&lt;td&gt;Sequential assignment&lt;/td&gt;
&lt;td&gt;Slight latency, better UX&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
&lt;td&gt;In-memory only&lt;/td&gt;
&lt;td&gt;Speed over durability&lt;/td&gt;
&lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;Closing Thoughts&lt;/h2&gt;

&lt;p&gt;Real-time matching systems succeed because they:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Separate location, availability, and assignment&lt;/li&gt;
  &lt;li&gt;Avoid expensive reindexing&lt;/li&gt;
  &lt;li&gt;Favor atomic operations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Great architectures don’t overload data structures — they compose them.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>algorithms</category>
      <category>architecture</category>
      <category>backend</category>
      <category>systemdesign</category>
    </item>
    <item>
      <title>How Uber Eats &amp; Zomato Find “Restaurants Near You"</title>
      <dc:creator>umesh kushwaha</dc:creator>
      <pubDate>Fri, 23 Jan 2026 12:30:42 +0000</pubDate>
      <link>https://forem.com/umesh_kushwaha_6655ba4c0d/how-uber-eats-zomato-find-restaurants-near-you-5f51</link>
      <guid>https://forem.com/umesh_kushwaha_6655ba4c0d/how-uber-eats-zomato-find-restaurants-near-you-5f51</guid>
      <description>&lt;h2&gt;Search &amp;amp; Discovery Architecture for Location-Based Systems (Deep Dive)&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Finding nearby restaurants looks simple. At scale, it’s a hard distributed systems problem involving spatial indexing, ranking, freshness, and tradeoffs between accuracy and performance.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This blog deep-dives into &lt;strong&gt;Search &amp;amp; Discovery&lt;/strong&gt; for location-based systems like:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Restaurant discovery (Zomato, Swiggy)&lt;/li&gt;
  &lt;li&gt;Store search (Blinkit, Instamart)&lt;/li&gt;
  &lt;li&gt;Nearby places (Google Maps-lite use cases)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;1️⃣ Problem Definition&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Inputs&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;User location (latitude, longitude)&lt;/li&gt;
  &lt;li&gt;Optional text query: “pizza”, “burger”, “south indian”&lt;/li&gt;
  &lt;li&gt;Filters: open now, rating, price, cuisine&lt;/li&gt;
  &lt;li&gt;Radius: 1–10 km&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Ranked list of nearby restaurants&lt;/li&gt;
  &lt;li&gt;Sorted by relevance, distance, and business signals&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Constraints&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Millions of restaurants&lt;/li&gt;
  &lt;li&gt;Low latency (&amp;lt; 200ms P95)&lt;/li&gt;
  &lt;li&gt;High read QPS&lt;/li&gt;
  &lt;li&gt;Data changes, but not every second&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;2️⃣ Nature of the Data&lt;/h2&gt;

&lt;p&gt;Understanding data behavior drives architectural decisions.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Attribute&lt;/th&gt;
      &lt;th&gt;Behavior&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
&lt;td&gt;Location&lt;/td&gt;
&lt;td&gt;Mostly static&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
&lt;td&gt;Name / Cuisine&lt;/td&gt;
&lt;td&gt;Rarely changes&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
&lt;td&gt;Ratings&lt;/td&gt;
&lt;td&gt;Periodic updates&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
&lt;td&gt;Open / Close status&lt;/td&gt;
&lt;td&gt;Time-based&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
&lt;td&gt;Query pattern&lt;/td&gt;
&lt;td&gt;Read-heavy&lt;/td&gt;
&lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;➡️ This is &lt;strong&gt;not a real-time problem&lt;/strong&gt;&lt;br&gt;
➡️ This &lt;strong&gt;is a search and indexing problem&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;3️⃣ High-Level Architecture&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;
User Request
     ↓
Search API
     ↓
Elasticsearch (Geo + Text)
     ↓
Source DB (Postgres / MySQL)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Optional Redis cache can be added for hot queries.&lt;/p&gt;




&lt;h2&gt;4️⃣ Why Elasticsearch?&lt;/h2&gt;

&lt;p&gt;Elasticsearch combines three critical capabilities:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Geo-spatial indexing&lt;/li&gt;
  &lt;li&gt;Full-text search&lt;/li&gt;
  &lt;li&gt;Relevance scoring and sorting&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Doing all three efficiently in a relational database becomes painful at scale.&lt;/p&gt;




&lt;h2&gt;5️⃣ Location Modeling&lt;/h2&gt;

&lt;h3&gt;Geo Point Mapping&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;{
  "location": {
    "type": "geo_point"
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This allows Elasticsearch to index latitude and longitude efficiently.&lt;/p&gt;




&lt;h2&gt;6️⃣ Geo Distance Query&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;{
  "query": {
    "bool": {
      "filter": {
        "geo_distance": {
          "distance": "5km",
          "location": {
            "lat": 12.9716,
            "lon": 77.5946
          }
        }
      }
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This avoids full scans and only evaluates nearby spatial segments.&lt;/p&gt;




&lt;h2&gt;7️⃣ How Elasticsearch Computes “Nearby”&lt;/h2&gt;

&lt;p&gt;Elasticsearch performs &lt;strong&gt;spatial preprocessing&lt;/strong&gt; using:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;BKD Trees&lt;/li&gt;
  &lt;li&gt;Geohash-based partitioning&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Restaurants are indexed into spatial cells. Queries only scan nearby cells.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Distance is calculated inflight only for filtered candidates.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;8️⃣ Preprocessing vs Inflight Computation&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Aspect&lt;/th&gt;
      &lt;th&gt;Preprocessing&lt;/th&gt;
      &lt;th&gt;Inflight&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
&lt;td&gt;Spatial segmentation&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
&lt;td&gt;Distance calculation&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
&lt;td&gt;Text relevance&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;9️⃣ Full-Text + Geo Search&lt;/h2&gt;

&lt;p&gt;Example: “pizza near me”&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{
  "query": {
    "bool": {
      "must": {
        "match": {
          "cuisine": "pizza"
        }
      },
      "filter": {
        "geo_distance": {
          "distance": "3km",
          "location": {
            "lat": 12.97,
            "lon": 77.59
          }
        }
      }
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;




&lt;h2&gt;🔟 Ranking Strategy&lt;/h2&gt;

&lt;p&gt;Distance alone is insufficient.&lt;/p&gt;

&lt;p&gt;Typical conceptual scoring:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
Final Score =
  Text Relevance
+ Rating Weight
+ Popularity Score
- Distance Penalty
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Scripted Sorting Example&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;{
  "_script": {
    "type": "number",
    "script": {
      "source": "doc['rating'].value * 2 - doc['distance'].value"
    },
    "order": "desc"
  }
}
&lt;/code&gt;&lt;/pre&gt;




&lt;h2&gt;1️⃣1️⃣ Radius Search Tradeoffs&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Small radius → faster, fewer results&lt;/li&gt;
  &lt;li&gt;Large radius → slower, noisier results&lt;/li&gt;
  &lt;li&gt;Dynamic radius → best UX&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Common approach: start small, expand if results are insufficient.&lt;/p&gt;




&lt;h2&gt;1️⃣2️⃣ Caching with Redis&lt;/h2&gt;

&lt;p&gt;Caching is optional but useful for hot locations.&lt;/p&gt;

&lt;p&gt;Example cache key:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
city:blr:lat:12.97:lon:77.59:radius:3km
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;TTL should be short (5–15 minutes).&lt;/p&gt;




&lt;h2&gt;1️⃣3️⃣ Why Not Redis GEO for Discovery?&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Redis GEO&lt;/th&gt;
      &lt;th&gt;Elasticsearch&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
&lt;td&gt;Fast&lt;/td&gt;
&lt;td&gt;Slightly slower&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
&lt;td&gt;No full-text&lt;/td&gt;
&lt;td&gt;Full-text search&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
&lt;td&gt;No ranking&lt;/td&gt;
&lt;td&gt;Advanced ranking&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
&lt;td&gt;Memory-heavy&lt;/td&gt;
&lt;td&gt;Disk-backed&lt;/td&gt;
&lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Redis GEO is better suited for real-time driver matching.&lt;/p&gt;




&lt;h2&gt;1️⃣4️⃣ Postgres + PostGIS?&lt;/h2&gt;

&lt;p&gt;It works, but with limitations.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Good for early-stage systems&lt;/li&gt;
  &lt;li&gt;Hard to scale ranking logic&lt;/li&gt;
  &lt;li&gt;Search complexity grows quickly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At scale, Elasticsearch wins.&lt;/p&gt;




&lt;h2&gt;1️⃣5️⃣ Data Freshness&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Ratings → async index updates&lt;/li&gt;
  &lt;li&gt;Menu changes → delayed propagation&lt;/li&gt;
  &lt;li&gt;Location changes → extremely rare&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Near real-time consistency is acceptable for discovery.&lt;/p&gt;




&lt;h2&gt;1️⃣6️⃣ Key Tradeoffs&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Elasticsearch complexity vs scalability&lt;/li&gt;
  &lt;li&gt;Preprocessing vs storage cost&lt;/li&gt;
  &lt;li&gt;Composite ranking vs explainability&lt;/li&gt;
  &lt;li&gt;Caching vs freshness&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;Closing Thoughts&lt;/h2&gt;

&lt;p&gt;Search &amp;amp; Discovery is fundamentally:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;An indexing problem&lt;/li&gt;
  &lt;li&gt;A ranking problem&lt;/li&gt;
  &lt;li&gt;A read-scalability problem&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>blog</category>
      <category>systemdesign</category>
      <category>distributedsystems</category>
    </item>
    <item>
      <title>Spring Boot vs .NET Core: Complete Developer Migration Guide</title>
      <dc:creator>umesh kushwaha</dc:creator>
      <pubDate>Tue, 04 Mar 2025 13:40:00 +0000</pubDate>
      <link>https://forem.com/umesh_kushwaha_6655ba4c0d/spring-boot-vs-net-core-complete-developer-migration-guide-4mfk</link>
      <guid>https://forem.com/umesh_kushwaha_6655ba4c0d/spring-boot-vs-net-core-complete-developer-migration-guide-4mfk</guid>
      <description>&lt;p&gt;Whether you’re moving from Spring Boot to .NET Core or vice versa — your transition guide is here&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Supported Languages&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="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%2Farticles%2F5adzbr444dprpietxsvx.png" class="article-body-image-wrapper"&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%2Farticles%2F5adzbr444dprpietxsvx.png" alt="Image description" width="800" height="276"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Both frameworks allow development in multiple languages, but Spring Boot is tied to JVM-based languages, while .NET Core is more flexible with multiple language options.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Supported Build Tools&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="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%2Farticles%2F0cmhj44x7p1w74gp6rws.png" class="article-body-image-wrapper"&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%2Farticles%2F0cmhj44x7p1w74gp6rws.png" alt="Image description" width="800" height="396"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Spring Boot primarily uses Maven or Gradle, while .NET Core uses MSBuild and &lt;code&gt;dotnet CLI&lt;/code&gt;. Dependency management is handled via Maven/Gradle in Spring Boot and NuGet in .NET Core.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Supported IDEs for Development&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="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%2Farticles%2Fthzhbdra837z7cmwe4nd.png" class="article-body-image-wrapper"&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%2Farticles%2Fthzhbdra837z7cmwe4nd.png" alt="Image description" width="800" height="396"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can choose any IDE what ever suits to you. I prefer IntelliJ for Spring Boot and VS Code for .Net Core.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Supported Embedded Servers&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="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%2Farticles%2Ftirrya74kwgqdabb75zf.png" class="article-body-image-wrapper"&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%2Farticles%2Ftirrya74kwgqdabb75zf.png" alt="Image description" width="800" height="396"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Spring Boot applications typically run on Tomcat by default but can be configured to use Jetty or Undertow. .NET Core applications use Kestrel by default but can be hosted behind IIS, HTTP.sys, or Nginx.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Project Setup &amp;amp; Structure&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Spring Boot Project Structure&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A typical Spring Boot project structure with multiple environment properties:&lt;/p&gt;

&lt;p&gt;&lt;a href="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%2Farticles%2Fumlteqs31zf3lmcqwcae.png" class="article-body-image-wrapper"&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%2Farticles%2Fumlteqs31zf3lmcqwcae.png" alt="Image description" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;.NET Core Project Structure&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A typical .NET Core project structure with multiple environment settings:&lt;/p&gt;

&lt;p&gt;&lt;a href="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%2Farticles%2Ftlszpr2oferhanwl9kaz.png" class="article-body-image-wrapper"&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%2Farticles%2Ftlszpr2oferhanwl9kaz.png" alt="Image description" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Both frameworks separate concerns using MVC architecture and include configuration files for managing environments. Additionally, both have a dedicated test structure to ensure test-driven development.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Application Initialization&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Spring Boot Initialization&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Spring Boot applications are initialized using &lt;code&gt;SpringApplication.run()&lt;/code&gt; in the &lt;code&gt;main&lt;/code&gt; method:&lt;/p&gt;

&lt;p&gt;&lt;a href="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%2Farticles%2Fniicagya094cbw32kgve.png" class="article-body-image-wrapper"&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%2Farticles%2Fniicagya094cbw32kgve.png" alt="Image description" width="800" height="243"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;.NET Core Initialization&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;.NET Core applications are initialized using &lt;code&gt;CreateDefaultBuilder()&lt;/code&gt; in &lt;code&gt;Program.cs&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="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%2Farticles%2Fm211ova5e36xn1b0i15s.png" class="article-body-image-wrapper"&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%2Farticles%2Fm211ova5e36xn1b0i15s.png" alt="Image description" width="800" height="467"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Startup Sequence &amp;amp; Main Application Entry Points&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="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%2Farticles%2F6nu9z75awnhzn8t5cbrj.png" class="article-body-image-wrapper"&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%2Farticles%2F6nu9z75awnhzn8t5cbrj.png" alt="Image description" width="800" height="467"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Spring Boot handles configuration automatically using &lt;code&gt;SpringApplication.run()&lt;/code&gt;, while .NET Core provides more explicit control via &lt;code&gt;Program.cs&lt;/code&gt; and &lt;code&gt;Startup.cs&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Dependency Injection&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Both Spring Boot and .NET Core support Dependency Injection (DI) for managing application components.&lt;/p&gt;

&lt;p&gt;&lt;a href="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%2Farticles%2Fk6a8br7ab0ealn6j6amv.png" class="article-body-image-wrapper"&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%2Farticles%2Fk6a8br7ab0ealn6j6amv.png" alt="Image description" width="800" height="467"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Registering Dependencies in Spring Boot&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="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%2Farticles%2F3lv6s0tb42c5zr36mrfx.png" class="article-body-image-wrapper"&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%2Farticles%2F3lv6s0tb42c5zr36mrfx.png" alt="Image description" width="800" height="549"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Registering Dependencies in .NET Core&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="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%2Farticles%2Fabf04bcto0y9sord602v.png" class="article-body-image-wrapper"&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%2Farticles%2Fabf04bcto0y9sord602v.png" alt="Image description" width="800" height="487"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Both frameworks support dependency injection, but while Spring Boot uses annotations, .NET Core relies on explicit configuration in &lt;code&gt;Startup.cs&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;CRUD Operations with ORM&lt;/strong&gt;
&lt;/h2&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Spring Boot CRUD Example&lt;/strong&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private String email;

    // Getters and Setters
}

@Repository
public interface UserRepository extends JpaRepository&amp;lt;User, Long&amp;gt; {}

@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;

    public User createUser(User user) {
        return userRepository.save(user);
    }

    public List&amp;lt;User&amp;gt; getAllUsers() {
        return userRepository.findAll();
    }

    public User updateUser(Long id, User userDetails) {
        User user = userRepository.findById(id).orElseThrow();
        user.setName(userDetails.getName());
        user.setEmail(userDetails.getEmail());
        return userRepository.save(user);
    }

    public void deleteUser(Long id) {
        userRepository.deleteById(id);
    }
}

@RestController
@RequestMapping("/users")
public class UserController {
    @Autowired
    private UserService userService;

    @PostMapping
    public User createUser(@RequestBody User user) {
        return userService.createUser(user);
    }

    @GetMapping
    public List&amp;lt;User&amp;gt; getAllUsers() {
        return userService.getAllUsers();
    }

    @PutMapping("/{id}")
    public User updateUser(@PathVariable Long id, @RequestBody User userDetails) {
        return userService.updateUser(id, userDetails);
    }

    @DeleteMapping("/{id}")
    public void deleteUser(@PathVariable Long id) {
        userService.deleteUser(id);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;.NET Core CRUD Example&lt;/strong&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class User {
    public int Id { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
}

public class UserService
{
    private readonly AppDbContext _context;
    public UserService(AppDbContext context) {
        _context = context;
    }
    public User CreateUser(User user) {
        _context.Users.Add(user);
        _context.SaveChanges();
        return user;
    }
    public IEnumerable&amp;lt;User&amp;gt; GetAllUsers() {
        return _context.Users.ToList();
    }
    public User UpdateUser(int id, User userDetails) {
        var user = _context.Users.Find(id);
        user.Name = userDetails.Name;
        user.Email = userDetails.Email;
        _context.SaveChanges();
        return user;
    }
    public void DeleteUser(int id) {
        var user = _context.Users.Find(id);
        _context.Users.Remove(user);
        _context.SaveChanges();
    }
}

[Route("api/users")]
[ApiController]
public class UserController : ControllerBase
{
    private readonly UserService _userService;
    public UserController(UserService userService) {
        _userService = userService;
    }
    [HttpPost]
    public ActionResult&amp;lt;User&amp;gt; CreateUser(User user) {
        return Ok(_userService.CreateUser(user));
    }
    [HttpGet]
    public ActionResult&amp;lt;IEnumerable&amp;lt;User&amp;gt;&amp;gt; GetUsers() {
        return Ok(_userService.GetAllUsers());
    }
    [HttpPut("{id}")]
    public ActionResult&amp;lt;User&amp;gt; UpdateUser(int id, User userDetails) {
        return Ok(_userService.UpdateUser(id, userDetails));
    }
    [HttpDelete("{id}")]
    public IActionResult DeleteUser(int id) {
        _userService.DeleteUser(id);
        return NoContent();
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here are the key differences between the CRUD approaches in Spring Boot and .NET Core:&lt;/p&gt;

&lt;p&gt;![]&lt;br&gt;
&lt;a href="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%2Farticles%2Fqjqpogx52c0677kz6bxc.png" class="article-body-image-wrapper"&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%2Farticles%2Fqjqpogx52c0677kz6bxc.png" alt="Image description" width="800" height="971"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Authentication &amp;amp; Authorization&lt;/strong&gt;
&lt;/h2&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Spring Boot Security&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Dependency&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.jsonwebtoken&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;jjwt&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;0.11.2&amp;lt;/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-security&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-web&amp;lt;/artifactId&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Security Configuration &amp;amp; Controller&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private UserDetailsService userDetailsService;

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
            .authorizeRequests()
            .antMatchers("/auth/**").permitAll()
            .anyRequest().authenticated()
            .and()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }
}

@RestController
@RequestMapping("/auth")
public class AuthController {
    @PostMapping("/login")
    public ResponseEntity&amp;lt;String&amp;gt; login(@RequestBody LoginRequest request) {
        // Authenticate and generate JWT token
        return ResponseEntity.ok("JWT-TOKEN");
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;.NET Core Identity Authentication&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Install Required Packages&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dotnet add package Microsoft.AspNetCore.Identity.EntityFrameworkCore
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Identity Configuration&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class ApplicationUser : IdentityUser {}

public class ApplicationDbContext : IdentityDbContext&amp;lt;ApplicationUser&amp;gt; {
    public ApplicationDbContext(DbContextOptions&amp;lt;ApplicationDbContext&amp;gt; options)
        : base(options) { }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Authentication Middleware in &lt;code&gt;Startup.cs&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;public void ConfigureServices(IServiceCollection services) {
    services.AddDbContext&amp;lt;ApplicationDbContext&amp;gt;(options =&amp;gt;
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

    services.AddIdentity&amp;lt;ApplicationUser, IdentityRole&amp;gt;()
        .AddEntityFrameworkStores&amp;lt;ApplicationDbContext&amp;gt;()
        .AddDefaultTokenProviders();

    services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(options =&amp;gt; {
            options.RequireHttpsMetadata = false;
            options.SaveToken = true;
            options.TokenValidationParameters = new TokenValidationParameters {
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("YOUR_SECRET_KEY")),
                ValidateIssuer = false,
                ValidateAudience = false
            };
        });
}

public void Configure(IApplicationBuilder app) {
    app.UseAuthentication();
    app.UseAuthorization();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Controller for Authentication&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[ApiController]
[Route("api/auth")]
public class AuthController : ControllerBase {
    private readonly SignInManager&amp;lt;ApplicationUser&amp;gt; _signInManager;
    private readonly UserManager&amp;lt;ApplicationUser&amp;gt; _userManager;

    public AuthController(UserManager&amp;lt;ApplicationUser&amp;gt; userManager, SignInManager&amp;lt;ApplicationUser&amp;gt; signInManager) {
        _userManager = userManager;
        _signInManager = signInManager;
    }

    [HttpPost("login")]
    public async Task&amp;lt;IActionResult&amp;gt; Login([FromBody] LoginRequest request) {
        var result = await _signInManager.PasswordSignInAsync(request.Username, request.Password, false, false);
        if (result.Succeeded) {
            return Ok("JWT-TOKEN");
        }
        return Unauthorized();
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Key differences between Spring security &amp;amp; .NET core Identity framework&lt;/p&gt;

&lt;p&gt;&lt;a href="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%2Farticles%2Fzxagg132qcum1hg9juig.png" class="article-body-image-wrapper"&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%2Farticles%2Fzxagg132qcum1hg9juig.png" alt="Image description" width="800" height="598"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Writing Unit Tests (TDD Approach)&lt;/strong&gt;
&lt;/h2&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Unit Testing Frameworks&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="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%2Farticles%2Fhwra6fsgl12mvxcjrcbe.png" class="article-body-image-wrapper"&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%2Farticles%2Fhwra6fsgl12mvxcjrcbe.png" alt="Image description" width="800" height="328"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sample Unit Test — Spring Boot&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@SpringBootTest
@RunWith(MockitoJUnitRunner.class)
public class UserServiceTest {

    @Mock
    private UserRepository userRepository;

    @InjectMocks
    private UserService userService;

    @Test
    public void testGetUserById() {
        User user = new User(1L, "John Doe");
        Mockito.when(userRepository.findById(1L)).thenReturn(Optional.of(user));

        User result = userService.getUserById(1L);
        assertEquals("John Doe", result.getName());
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Sample Unit Test — .NET Core&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class UserServiceTest {
    private readonly Mock&amp;lt;IUserRepository&amp;gt; _userRepositoryMock;
    private readonly UserService _userService;

    public UserServiceTest() {
        _userRepositoryMock = new Mock&amp;lt;IUserRepository&amp;gt;();
        _userService = new UserService(_userRepositoryMock.Object);
    }

    [Fact]
    public void TestGetUserById() {
        var user = new User { Id = 1, Name = "John Doe" };
        _userRepositoryMock.Setup(repo =&amp;gt; repo.GetById(1)).Returns(user);

        var result = _userService.GetUserById(1);
        Assert.Equal("John Doe", result.Name);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Running &amp;amp; Testing the Application&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Spring Boot&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="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%2Farticles%2F0sdyuz6hjj3bqzvylcf7.png" class="article-body-image-wrapper"&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%2Farticles%2F0sdyuz6hjj3bqzvylcf7.png" alt="Image description" width="800" height="398"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;.NET Core&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="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%2Farticles%2F8s9fz2lx6b21pcd55j23.png" class="article-body-image-wrapper"&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%2Farticles%2F8s9fz2lx6b21pcd55j23.png" alt="Image description" width="800" height="398"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;References&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Spring Boot&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.spring.io/spring-boot/docs/current/reference/html/" rel="noopener noreferrer"&gt;Spring Boot Official Documentation&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://spring.io/projects/spring-security" rel="noopener noreferrer"&gt;Spring Security Guide&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://spring.io/projects/spring-data-jpa" rel="noopener noreferrer"&gt;Spring Data JPA&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;.NET Core&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://learn.microsoft.com/en-us/dotnet/core/" rel="noopener noreferrer"&gt;.NET Core Official Documentation&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://learn.microsoft.com/en-us/aspnet/core/security/" rel="noopener noreferrer"&gt;ASP.NET Core Security&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://learn.microsoft.com/en-us/ef/core/" rel="noopener noreferrer"&gt;Entity Framework Core&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>java</category>
      <category>springboot</category>
      <category>netcore</category>
      <category>csharp</category>
    </item>
  </channel>
</rss>
