Unique field olayı işimizi çok kolaylaştıran bir özellik. Özellikle web uygulaması yazıyorsak. API'da mongoose kullandığımızı düşünelim, kullanıcının username'i unique olmak zorunda ve bunu kontrol etmek için kullanıcıyı create ederken ve kullanıcıyı update ederken de gelen username değerinin -tabi update'de geliyorsa- başka bir kullanıcıda var mı ? Bu username değerini kullanabilir mi ? Gibi kontroller ile arka tarafta bize zorluk çıkarıyor. İşlerimizi zorlaştırıyor.
Update endpointi için konuşursak, gelen request body'de username var mı ? Username varsa bu username değeri ben hariç başka kullanıcılarda var mı? Yoksa update işlemini yap. Gibi ortaya sorgular çıkıyor, bir de javascriptin promise yapısı, callback olayları iç içe yazmamıza neden oluyor ve al başına belayı.. Kodumuz uzadıkça ortaya daha çirkin bir yapı çıkacak ve bu hiç hoş değil... Üstelik biz bu işlemi kendimiz yaptığımız için acaba yeni yazdığım endpointte böyle bir kontrol yaptım mı ? Gibi kafalarda da soru işareti ve korku bırakacak. Belki de farklı bir döküman yapısındaki bir değer unique olmalı ama orda kontrol etmeyi unuttuk...
Ama mongoose'daki unique özelliğini kullanırsak kullanıcı istediği endpointten email değerini güncellemeye çalışsa da mongoose hata fırlatıcaktır. Ve tek yapmamız gereken promise yapısına sahip sorgularda catch ile hata fırlatılmış mı diye kontrol etmek olacak. Birazcık kodla gösterelim..
Örnek projemiz şöyle iki dosyadan oluşuyor. Çok fazla kod olmasın ekrana sığsın diye her şeyi basit ve kısa tutmaya çalıştım. /register endpointine gelen post isteğindeki request bodyi doğrudan model'ımın içine aktarıyorum ve model'ımı kaydetmeye çalışıyorum.
Tabi model'ın şemasında 1 tane değer var o da username, bu değer de unique olmalı. required değeri de true, hatayı da yanda verdiğimiz string gibi dönecek. Tabi şöyle eksik bir kod da var, req.body'i modelın içine koyduktan sonra validate methodu ile kontrol edip ortaya çıkan tüm validation errorları kullanıcıya response edebilirdik.( Link ) Ama üşendim ^^ bir de konumuz değil.
Almayı beklediğimiz unique hatasını alalım ve neyi başardık görelim.
İlk request başarılı:
Yine aynı username ile kayıt olmaya çalıştığımızda ise hata dönecek ve kaydetmeyecek:
Full JSON şöyle:
{ "message": "Veritabanı Hatası: MongoError: E11000 duplicate key error collection: mongo_unique.users index: username_1 dup key: { : \"test123\" }" }
Hata mesajı çok da anlaşılır değil görüldüğü gibi tabi bunu şöyle handle edebiliriz.
if(err.message.includes('E11000')) { res.status(422).send({message: 'Bazı değerler unique'tir...'}) }
Tabi bu da güzel bir çözüm değil görüldüğü gibi. Hangi değer unique frontend bunu nasıl anlayacak ? Error message'ı da verelim içinde nasıl olsa fieldın adı geçiyor mu demeliyiz ?
Bu çok yanlış bir yaklaşım hata mesajında field adı arayacak olan ve düzgün bir data sunması gereken her zaman backendtir. O yüzden sakın böyle bir şey yapmayın. Yukarıda attığım linkte de görüldüğü gibi :
unique option validator olmadığı için biz öncesinde bir validasyon yapıp kullanıcıya anlamlı bir mesaj sunamıyoruz. Şu şu fieldlar hatalı işte hata mesajları da şöyle şeklinde bir json [{field: errorMessage}, ...]
Ya error messageı parse ederek hata veren fieldlar için anlamlı mesajları biz oluşturucaz ya da şöyle bir plugin yazılmış onu kullanıcaz: Link
npm ile bu kütüphaneyi kurduktan sonra kodumuzu birazcık değiştirelim:
Ve sonuca bakalım :
Evet işte istediğimiz sonuç :^)
Okuduğunuz için teşekkür ederim umarım faydalı olmuştur :+)
Kalın sağlıcakla.
0 yorum:
Yorum Gönder