.NET ile Olceklenebilir REST API’leri Olusturma: En Iyi Uygulamalar ve Uygulama Rehberi
Gunumuzun dagitik sistem ortaminda, REST API’leri modern uygulama mimarisinin temelidirler. Microservisler, mobil arka uçlar insa ediyorsanız veya ücüncü taraf sistemleri entegre ediyorsanız, iyi tasarlanmis bir .NET API basarili bir platform ile zorluk ceken platform arasindaki farki olusturabilir.
ByteGurus’ta, gunluk milyonlarca isteği isleyen yuksek performansli REST API’leri mimarlandirmaya ve yayinlamaya yardimci olduk. Bu rehberde, uretim ortamlarinda isleyen stratejileri ve teknikleri paylasacagiz.
Olceklenebilir API’ler Icin Neden .NET?
Dot NET, kurulusundan bu yana dramatik sekilde gelisti. Modern .NET (ozellikle .NET 6, 7 ve 8), olceklenebilir REST API’leri insa etmek icin ilgi cekici avantajlar sunar:
- Yuksek performans: Kiyaslamalar tutarli sekilde .NET’i API gelistirme icin en hizli cerceveler arasinda gosterir
- Birlestiralmis ekosistem: Web, masaustu ve mobil uygulamalarini paylastilan kutuphane ile olusturun
- Async-first mimarisi: Binlerce esanlamli baglantiyı islemek icin dogal async/await destegi
- Zengin araclar: Visual Studio ve komut satiri araclari muthis gelistirme deneyimi saglar
- Kurumsal destek: Microsoft tarafindan desteklenir, uzun vadeli destek donumleri ile
Olceklenebilirlik Icin Mimari Ilkeler
Kod yazmadan once, solid bir mimari temel kurun.
Kayginin Ayrilmasi
.NET API projenizi net katmanlarla organize edin:
- Sunum Katmani: HTTP isteklerini isleyen denetleyiciler
- Uygulama Katmani: Isletme mantigi ve orkestrasyonu
- Domain Katmani: Cekirdek isletme kurallari ve varliklari
- Altyapi Katmani: Veritabani erisimi, dis hizmetler ve mesajlasma
Bu yapı, kodunuzun buyudukce bakimi kolay ve test edilebilir hale gelir.
Bagimliligi Enjeksiyonu
ASP.NET Core yerli bagimliligi enjeksiyonu icerirken, bu olceklenebilir uygulamalar icin kritiktir. Uygun DI testi etkinlestirir, baglantiyı azaltir ve kodunuzu daha moduler hale getirir:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IUserRepository, UserRepository>();
services.AddScoped<IUserService, UserService>();
services.AddControllers();
}
}
Asinkron Isleme
.NET API’nizdeki iş parcaçiklari asla engellemeyin. Yigininin tamaminda async/await kullanin:
[HttpGet("{id}")]
public async Task<ActionResult<UserDto>> GetUserById(int id)
{
var user = await _userService.GetUserByIdAsync(id);
if (user == null)
return NotFound();
return Ok(user);
}
Bu, tek bir sunucunun katlanarak daha fazla esanlamli istegi islemesine izin verir.
En Iyi Uygulamalari Uygulama
1. Entity Framework Core’u Verimli Kullanin
Entity Framework Core guclüdür ancak olcekte dikkatli kullanilmasi gerekir. Su uygulamalari uygulayın:
public class UserRepository : IUserRepository
{
private readonly ApplicationDbContext _context;
public UserRepository(ApplicationDbContext context) => _context = context;
public async Task<User> GetUserWithOrdersAsync(int userId)
{
return await _context.Users
.Include(u => u.Orders)
.AsNoTracking() // Salt okunur sorgular icin performansi arttirir
.FirstOrDefaultAsync(u => u.Id == userId);
}
public async Task<IEnumerable<User>> GetActiveUsersAsync(int pageNumber, int pageSize)
{
return await _context.Users
.Where(u => u.IsActive)
.OrderByDescending(u => u.CreatedAt)
.Skip((pageNumber - 1) * pageSize)
.Take(pageSize)
.AsNoTracking()
.ToListAsync();
}
}
Ana stratejiler:
- Salt okunur sorgular icin
AsNoTracking()kullanin - Buyuk veri setlerinin yuklenmesini onlemek icin sayfalandirma uygulayın
- Tembel yukleme yerine acik
Include()ifadelerini kullanin - Yalnizca gerekli sutunlari getirmek icin projeksiyonlari kullanin
2. Onbellekleme Stratejileri
Veritabani yukünü azaltmak icin birden fazla seviyede onbellekleme uygulayın:
public class UserService : IUserService
{
private readonly IUserRepository _repository;
private readonly IMemoryCache _cache;
private const string UserCacheKeyPrefix = "user_";
public UserService(IUserRepository repository, IMemoryCache cache)
{
_repository = repository;
_cache = cache;
}
public async Task<UserDto> GetUserByIdAsync(int id)
{
string cacheKey = $"{UserCacheKeyPrefix}{id}";
if (_cache.TryGetValue(cacheKey, out UserDto cachedUser))
return cachedUser;
var user = await _repository.GetUserByIdAsync(id);
if (user != null)
{
var cacheOptions = new MemoryCacheEntryOptions()
.SetAbsoluteExpiration(TimeSpan.FromMinutes(30));
_cache.Set(cacheKey, user, cacheOptions);
}
return user;
}
}
Dagitik sistemler icin Redis’i degerlendirin:
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = configuration.GetConnectionString("Redis");
});
3. Istek/Yanit Sikistirmasi
Bant genisligi tuketimini azaltin:
public void ConfigureServices(IServiceCollection services)
{
services.AddResponseCompression(options =>
{
options.Providers.Add<GzipCompressionProvider>();
options.MimeTypes = ResponseCompressionDefaults.MimeTypes
.Concat(new[] { "application/json" });
});
}
public void Configure(IApplicationBuilder app)
{
app.UseResponseCompression();
}
4. Hiz Sinirlamasi ve Azaltma
API’nizi kotu kullanimdan koruyun ve adil kaynak dagitimini saglayin:
services.AddRateLimiter(rateLimiterOptions =>
{
rateLimiterOptions.AddFixedWindowLimiter(policyName: "fixed", options =>
{
options.PermitLimit = 100;
options.Window = TimeSpan.FromMinutes(1);
});
});
app.UseRateLimiter();
Gercek Dunyadaki Kullanim Orneği: E-Ticaret API’si
Mevsimsel artislari isleyen bir e-ticaret platformu icin .NET API’si olusturmayı dusunun:
- CQRS Uygulayın: Bagimsiz olceklendirme icin okuma ve yazma islemlerini ayirin
- Mesaj Kuyruklerini Kullanin: Uzun sureli islemleri (siparis isleme, e-posta bildirimleri) arka plan calisan programlarina yükleyin
- Veritabani Optimizasyonu: Urun katalogu partisyon, envanter sorgusu icin okuma replikasi kullanin
- API Surumlemesi: Birden fazla API surumuyle gelismepli planlama
- Izleme: Performans izleme icin Application Insights uygulayın
Yayin Hususlari
Konteyneristirme
.NET API’nizi tutarli yayin icin Docker’da paketi:
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY ["MyApi.csproj", "./"]
RUN dotnet restore
COPY . .
RUN dotnet publish -c Release -o /app/publish
FROM mcr.microsoft.com/dotnet/aspnet:8.0
WORKDIR /app
COPY --from=build /app/publish .
ENTRYPOINT ["dotnet", "MyApi.dll"]
Yatay Olceklendirme
.NET API’nizi durumsuz olmasi icin tasarlayin ve yuk dengeleyicisinin arkasinda birden fazla ornegi calisbirin. Oturum durumunu islem ici depolamada degil, dagitik onbelleklerde saklin.
Izleme ve Gorulürlük
Olcülen seyleri isleme getirilir. Kapsamli izleme uygulayın:
public void ConfigureServices(IServiceCollection services)
{
services.AddApplicationInsightsTelemetry();
services.AddLogging(builder =>
{
builder.AddApplicationInsights();
});
}
Ana metrikler izleyin:
- Yanit sureleri ve gecikme yuzdelikleri
- Hata oranlari ve turleri
- Veritabani sorgusu performansi
- Onbellege isabet oranlari
- Kaynak kullanimi
Sonuc
.NET ile olceklenebilir REST API’leri olusturmak, mimari, performans optimizasyonu ve operasyonel mükemmeliyete dikkat gerektirir. Bu uygulamalar - uygun katmanlamadan ve onbelleklemeden izleme ve yayina kadar - gücü tutarli bir sekilde isleyen API’ler olusturacaksiniz.
.NET ekosistemi bu yolculuk icin muthis araclar ve cerceveler saglar. Sifirdan baslayin veya mevcut sistemleri optimize ederseniz, burada belirtilen ilkeler sizi yillar boyunca isletmeyi yapmayan eglencelik, performansli API’lere yonlendirecektir.
ByteGurus’ta, bu sistemleri uretimde mimarlamaya ve yayinlamaya yardimci oluyoruz. Onemli bir API baslatmayi planliyorsanız, basarinizi nasil hizlandirabileceğimizi konusalim.
ByteGurus
Yazar