TGViewer
C# Geeks (.NET) C# Geeks (.NET) @csharpgeeks · 550 subscribers
Post #401 229
🚀 طراحی و پیاده‌سازی URL Shortener در NET. — بخش نهایی

در این بخش، بعد از آماده‌سازی منطق اصلی سیستم، می‌خواهیم دو Endpoint اصلی را پیاده‌سازی کنیم:
1️⃣ کوتاه‌سازی لینک (URL Shortening)
2️⃣ ریدایرکت کاربر به لینک اصلی (URL Redirection)

🔗 کوتاه‌سازی لینک (URL Shortening)

در ابتدا، با استفاده از یک Minimal API ساده، یک Endpoint برای کوتاه‌سازی URL ایجاد می‌کنیم.
این Endpoint یک URL را از کاربر می‌گیرد، آن را اعتبارسنجی می‌کند، سپس با کمک سرویس UrlShorteningService، یک کد منحصربه‌فرد تولید کرده و لینک کوتاه‌شده را در دیتابیس ذخیره می‌کند. در نهایت، لینک کوتاه‌شده به کاربر بازگردانده می‌شود.
public record ShortenUrlRequest(string Url);

app.MapPost("shorten", async (
ShortenUrlRequest request,
UrlShorteningService urlShorteningService,
ApplicationDbContext dbContext,
HttpContext httpContext) =>
{
if (!Uri.TryCreate(request.Url, UriKind.Absolute, out _))
{
return Results.BadRequest("The specified URL is invalid.");
}

var code = await urlShorteningService.GenerateUniqueCode();

var httpRequest = httpContext.Request;

var shortenedUrl = new ShortenedUrl
{
Id = Guid.NewGuid(),
LongUrl = request.Url,
Code = code,
ShortUrl = $"{httpRequest.Scheme}://{httpRequest.Host}/{code}",
CreatedOnUtc = DateTime.UtcNow
};

dbContext.ShortenedUrls.Add(shortenedUrl);
await dbContext.SaveChangesAsync();

return Results.Ok(shortenedUrl.ShortUrl);
});


📌 نکته:

در اینجا احتمال اندکی از Race Condition وجود دارد — چون ابتدا کد تولید می‌شود و بعد در دیتابیس ذخیره می‌گردد. ممکن است دو درخواست هم‌زمان، یک کد مشابه تولید کنند.
اما از آنجا که در دیتابیس Unique Index تعریف کرده‌ایم، جلوی درج مقادیر تکراری گرفته می‌شود.

🔁 ریدایرکت به URL اصلی (URL Redirection)

در سناریوی دوم، وقتی کاربر روی لینک کوتاه کلیک می‌کند، سیستم باید او را به لینک اصلی هدایت کند.

برای این کار یک Endpoint دیگر ایجاد می‌کنیم که کد کوتاه‌شده را از مسیر (route parameter) می‌گیرد و در دیتابیس جست‌وجو می‌کند.

اگر لینک پیدا شد، کاربر به آدرس اصلی Redirect می‌شود.
app.MapGet("{code}", async (string code, ApplicationDbContext dbContext) =>
{
var shortenedUrl = await dbContext
.ShortenedUrls
.SingleOrDefaultAsync(s => s.Code == code);

if (shortenedUrl is null)
{
return Results.NotFound();
}

return Results.Redirect(shortenedUrl.LongUrl);
});

📨 در صورت موفقیت، پاسخ HTTP با کد وضعیت 302 (Found) بازگردانده می‌شود که نشان‌دهندهٔ ریدایرکت موقت است.

⚡️ نقاط قابل بهبود در سیستم کوتاه‌کننده لینک

اگرچه پیاده‌سازی فعلی کاملاً قابل‌استفاده است، اما می‌توان با چند بهبود ساده آن را مقیاس‌پذیرتر و حرفه‌ای‌تر کرد:

1️⃣ Caching 🧠
استفاده از Redis برای کش کردن لینک‌ها و کاهش بار دیتابیس.

2️⃣ Horizontal Scaling ⚙️
طراحی سیستم برای مقیاس‌پذیری افقی و مدیریت ترافیک بالا.

3️⃣ Data Sharding 🧩
تقسیم داده‌ها بین چند دیتابیس برای بهبود کارایی و توزیع بار.

4️⃣ Analytics 📊
افزودن تحلیل‌ها برای رصد تعداد کلیک‌ها، موقعیت کاربران و نرخ استفاده.

5️⃣ User Accounts 👤
امکان ایجاد حساب کاربری برای مدیریت لینک‌های کوتاه‌شده توسط هر کاربر.

✅ حالا شما یک سیستم کامل URL Shortener با NET. دارید!
می‌توانید این پروژه را گسترش دهید و با افزودن قابلیت‌های بالا، آن را به یک راهکار مقیاس‌پذیر و قدرتمند در سطح تولید (Production) تبدیل کنید.

🔖هشتگ‌ها:
#URLShortener #SystemDesign
More from @csharpgeeks
  1. Sep 22, 2026یه مدتی قراره از دنیای NET. فاصله بگیرم، چون وقتشه برم سربازی. راستش نمیدونم این مدت رو چج…
  2. Sep 20, 2026🔥 حالا مشکل اصلی: Alert Storm فرض کن Database از دسترس خارج شده. ۱۰۰ Pod داری. هر Pod می‌…
  3. Sep 20, 2026🚨 طراحی سیستم Monitoring و Alerting در یک سیستم بزرگ فرض کن ساعت ۳ صبح است. سیستم شما با…
  4. Sep 19, 2026#Engineering_Leadership تصمیم نگرفتن هم یک تصمیم است یه چیز عجیب توی تیم‌های مهندسی: گاهی…
  5. Sep 19, 2026☑ چک‌لیست آماده‌سازی تیم، فرایندها و زیرساخت برای توسعه با AI توجه: هیچ چک‌لیستی جهان‌شمول…
  6. Sep 19, 2026📌پایان یک انتظار طولانی: اعتبارسنجی ناهمگام (Async Validation) در NET 11.
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →