Linux'ta .NET Aspire'da Get By ID Endpointi Ekleme
[[academy-video-youtube({"vid": "hMhA5sLHUpY", "start_time": "0", "title": "Linux'ta .NET Aspire'a Get By ID Uç Noktası Ekleme", "creator": "Tim Corey", "length": "15dk 20sn"})]]
Bir veritabanı tablosundaki her kaydı döndürmek listeleme sayfaları için kullanışlıdır, ancak çoğu API tüketicisi ayrıca kimliğiyle tek bir kayıt almayı da ister. Bu ikinci uç nokta, "tümünü al" yolunun gerektirmediği kararları tanıtır: tek bir nesneye karşı bir koleksiyon için hangi dönüş türü anlamlı, kimlik herhangi bir kayıtla eşleşmediğinde ne olur ve bu hatayı doğru HTTP durum kodu ile arayana nasıl iletilir.
Tim Corey, Linux üzerinde .NET Aspire'da 'Kimlik ile Getirme Uç Noktası Ekleme' adlı videosunda Tiny Ticket API'yi GET /api/tickets/{id} uç noktası ekleyerek devam ettiriyor. Mevcut güzergahın bir kopyala-yapıştırı olarak başlayan şey, tek bir nesneyi (bir dizin yerine) döndürmek, null sonuçları kontrol etmek ve kimlik mevcut olmadığında bileti içeren 200 OK veya 404 Not Found döndürmek için TypedResults kullanmak da dahil olmak üzere kenar durumlar ile canlı bir yürüyüşe dönüşür. Linux'ta C# serisini takip ediyorsanız veya doğru durum kodu yanıtlarına ihtiyaç duyan minimal API'ler geliştiriyorsanız, bu bölüm tam düşünce sürecini kapsar.
Başlamak için Tümünü Alma Yolunu Kopyalama
[0:35 - 1:45] Tim, API hizmetinin Program.cs dosyasını açıyor ve mevcut GET /api/tickets uç noktasını kopyalıyor. Yeni güzergah bilet kimliği için bir yol parametresine ihtiyaç duyar, bu nedenle URL deseni {id:int} içerecek şekilde değişir ve işlemcisi bir int id parametresi alır. Saklı yordam referansı, bir kimlik parametresi bekleyen spTickets_GetAll'den spTickets_Get'e geçiş yapar.
app.MapGet("/api/tickets/{id:int}", async (int id, IDbConnection db) =>
{
var tickets = await db.LoadSqlAsync<TicketModel>("spTickets_Get", new { id });
// Initial version: returns a list, which we'll fix next
return tickets;
});app.MapGet("/api/tickets/{id:int}", async (int id, IDbConnection db) =>
{
var tickets = await db.LoadSqlAsync<TicketModel>("spTickets_Get", new { id });
// Initial version: returns a list, which we'll fix next
return tickets;
});Dikkate değer bir adlandırma kolaylığı: saklı yordam parametresi küçük harfle id olarak yazılmıştır, bu C# parametre adıyla tam olarak eşleşir. Bu, Dapper'ın anonim nesneyi new { id } belirtmeden doğrudan eşleştirebileceği anlamına gelir. SQL parametresi farklı bir şekilde kullanılırsa, anonim nesnenin new { Id = id } gibi açık bir özellik atamasına ihtiyacı olurdu.
Bir Liste Yerine Tek Bir Nesne Döndürme
[2:39 - 4:16] Swagger üzerinden yapılan ilk test, bir sorun ortaya koyar: ID 2'yi geçirmek, doğru biletle 200 döndürür, ancak yanıt gövdesi bir JSON dizisi içinde sarılır. Bir arayan, ID ile tek bir kaynağı istediğinde, bir eleman içeren bir koleksiyon değil, tek bir nesne beklerler.
Sorgu sonucuna .FirstOrDefault() eklemek, sarmalamayı düzeltir. Liste öğeler içeriyorsa FirstOrDefault ilk öğeyi döndürür, liste boşsa null döndürür. Bu, dizi sorununu çözer ancak yeni bir soru tanıtır: ID herhangi bir kayıtla eşleşmediğinde API ne döndürmelidir?
var output = tickets.FirstOrDefault();var output = tickets.FirstOrDefault();Tek satırlık değişiklik, mevcut kayıtlar için doğru yanıt şeklini üretir. Bununla birlikte, veritabanında bulunmayan 4 kimlik ile test yapmak daha derin bir boşluk ortaya çıkarır. Yanıt, 200 durum koduyla birlikte null olarak geri gelir. Bu, teknik olarak geçerli bir HTTP'dir fakat, arayanı yanıltır: bir 200, isteğin başarılı olduğunu ve kaynağın bulunduğunu belirtir, oysa gerçekte hiçbir şey eşleşmiyordu.
Bulunamadığı Durumları TypedResults ile Ele Alma
[4:41 - 11:44] Bu bölümde, Tim gerçek zamanlı tasarım kararlarını çalışırken, son kodu okumaktan ziyade izlemenin değerli olmasını sağlıyor. Düşünce süreci birkaç yinelemeden geçiyor:
Öncelikle, liste boş olduğunda bir istisna atan .FirstOrDefault() yerine .First() kullanmayı düşünüyor. Bu, bir sunucu hatasını ima eden 500 hatası üretir, bu da bir null 200'den daha kötüdür, çünkü 500 sunucu hatası yerine eksik kaynak olduğunu ima eder.
Sonra geri adım atılarak bir null kontrolü oluşturur. Sonucu bir değişkene kaydeder, null olup olmadığını kontrol eder ve her duruma farklı yanıtlar döndürür. Meydan okuma, minimal bir API işleyicisinin birden fazla yanıt şekli döndürebileceğinde dönüş türünü açık olarak bildirmesi gerektiğidir.
Çözüm TypedResults'dır, bu yanıt türlerini metod imzasında belirtmenize olanak tanır.
app.MapGet("/api/tickets/{id:int}", async Task<Results<Ok<TicketModel>, NotFound>> (int id, IDbConnection db) =>
{
var tickets = await db.LoadSqlAsync<TicketModel>("spTickets_Get", new { id });
var output = tickets?.FirstOrDefault();
if (output is null)
{
return TypedResults.NotFound();
}
return TypedResults.Ok(output);
});app.MapGet("/api/tickets/{id:int}", async Task<Results<Ok<TicketModel>, NotFound>> (int id, IDbConnection db) =>
{
var tickets = await db.LoadSqlAsync<TicketModel>("spTickets_Get", new { id });
var output = tickets?.FirstOrDefault();
if (output is null)
{
return TypedResults.NotFound();
}
return TypedResults.Ok(output);
});Bu dönüş türü olan Task<Results<Ok<TicketModel>, NotFound>>, bu uç noktanın 200 ile bir TicketModel gövdesi veya gövdesiz bir 404 ürettiğini çerçeveye (ve Swagger'a) bildirir. VS Code'da renkli köşeli parantez eşleşmesi, genel sonuç türleriyle hızla yığılan köşeli parantez gruplarını gezinmeye yardımcı olur.
Test sırasında yüzeye çıkan ince bir hata, ilk versiyonun TypedResults.NotFound() çağırması ancak return etmemesidir. Uç nokta derlenir çünkü NotFound() geçerli bir ifadedir, ancak return anahtarı olmadan, yürütme Ok yoluna kayar. Tim, Swagger hala eksik bir kimlik için 200 gösterdiğinde bu durumu yakalar, return ekler ve 404 bir sonraki çalıştırmada doğru şekilde görünür.
Swagger'da Her İki Yolu Test Etme
[11:44 - 14:09] Son kod yerine koyulduğunda, Tim Swagger UI'sinde her iki senaryo üzerinde çalışır. ID 3'ü geçirmek, bilet nesnesi ile 200 döndürür. ID 4'ü geçirmek, boş bir yanıt gövdesi ile 404 döndürür.
Swagger arayüzünde ilk kez kullanıcıları yanıltabilecek bir ayrıntı da işaret eder: 'Yanıtlar' bölümünün, yürüt düğmesinin altında, olası yanıt kodlarını (200 ve 404) gösterdiğini, gerçek sonucu göstermediğini. Gerçek sunucu yanıtı, o bölümün üstünde ayrı bir panelde görünür. İki paneli karıştırmak, 'neden 200 alıyorum?' karışıklığının yaygın bir kaynağıdır.
TypedResults yaklaşımı aynı zamanda Swagger belgelerini otomatik olarak geliştirir. Çünkü dönüş türü hem Ok<TicketModel> hem de NotFound'yi deklare eder, Swagger her ikisini de kendi şemaları ile potansiyel sonuçlar olarak gösterir. API belgelerini okuyan çağırıcılar, ayrı OpenAPI açıklamaları yazmadan bir 404 durumunu ele almaları gerektiğini bilirler.
Tamamlamak: Özelliklerden Önce Kenar Durumlar
[14:09 - 15:09] Başlangıçta tümünü al uç noktasının basit bir kopyala-yapıştırı olan şey, API tasarımında daha derin bir egzersize dönüştü. Son versiyon, mutlu yolu (kayıt bulundu), beklenen hatayı (kayıt bulunamadı) ve beklenmedik senaryolar için savunma amaçlı bir null kontrolü (sorgu null döndürüyor) ele alır. Tim'in çalışırken canlı bir şekilde bu durumları çözme yaklaşımı, üretim uç noktalarının gerektirdiği türden iteratif düşünmeyi gösterir.
Sonuç
[15:09 - 15:20] Minimal bir API'ye kimlik ile getir uç noktası eklemek, güzergah tanımının ötesinde üç karar içerir: koleksiyonu açmak için FirstOrDefault kullanmak, 'bulunamadı'yı 'bulundu'dan ayırt etmek için null kontrol etmek ve çerçevenin doğru HTTP durum kodunu döndürmesi için dönüş türüne TypedResults beyan etmek. Results<Ok<t>, NotFound> deseni, başarı veya yokluğunu belirtmesi gereken herhangi bir uç nokta boyunca yeniden kullanılabilir.
Seri navigasyonu: Bu makale, Tiny Ticket uygulamasını oluşturan Linux üzerinde C# serisinin bir parçasıdır. Önceki: Swagger UI Ekleme. Sonraki: POST Ekleme Ucu Eklemek.
Örnek İpucu: Minimal API işleyiciniz birden fazla olası durum kodu döndürüyorsa, her zaman bunları Results<> generic içinde ilan edin. Bu, otomatik olarak doğru Swagger belgesini oluşturur ve her kod yolunun geçerli bir sonuç türü döndürdüğünü doğrulaması için derleyiciyi zorlar.
Tam videoyu YouTube Kanalında izleyin ve C# üzerinde Linux serisinde sağlam API uç noktaları oluşturma hakkında daha fazla bilgi edinin.

