DTO ve AutoMapper Zaman Kaybı mı Güvenlik Kalkanı mı?

Kemal Talha KOÇ
5 min readAug 11, 2024

--

DTO, Data transfer object in kısaltmasıdır. Yani data taşıma nesnesidir. Bu nesne bir apinin request ve response nesnesi olabileceği gibi, katmanlar arasında data transfer nesnesi de olabilir. Burada DTO dan kasıt, ismi dto ile biten nesneler değil, farklı katmanlara özel modellerin oluşturulmasıdır. Bu şekilde data alt katmandan üst katmanlara farklı modeller ile taşınmaktadır. Bu modellerin birbirine eşitlenmesinde de genellikle automapper, mapster ve benzeri kütüphaneler kullanılmaktadır. Örneğin 3 katmanlı bir API projesi olsun. Bunlar Presentation, Service, ve Data katmanları olsun. Data katmanındaki entity db objesi vardır. Service katmanında bu db objesi kullanılıp API katmanına veriliyorsa dto yoktur, ancak farklı bir modele çevirilip API de kullanılıyorsa dto kullanımı vardır. İsminin DTO ile bitip bitmemesi bu durumu değiştirmeyecektir. Amaç db nesnesi ile clienta verilen datayı izole etmektir. Aşağıda dto kullanılan ve kullanılmayan örnekler gösterilmiştir:

1. DTO Kullanılmayan Örnek

Bu örnekte, Presentation katmanında doğrudan veritabanı (DB) nesneleri kullanılacaktır. DTO kullanılmayacak.

Bu örnekte, UserController doğrudan User entity'sini kullanıyor, yani DTO kullanılmıyor. Veriler doğrudan DB entity'si üzerinden taşınıyor.

2. DTO Kullanılan Örnek

Bu örnekte, Presentation katmanında DTO kullanılacak ve veriler, DTO nesneleri ile taşınacaktır.

Yukarıdaki DTO lu örnekte doğru DTO kullanım örneği gösterilmiştir. Bunun yerine Service katmanında da User nesnesi kullanılıp API katmanında api response una map edilerek de aynı sonuç elde edilebilir.

Dto Kullanımının Avantajları

Çoğumuz, yazılımcı olarak büyük, çok katmanlı veya soğan halkası mimarilerinin kullanıldığı projelerde çalışıyoruz. Bu projelerde, birden fazla yazılımcı ile iş birliği yapıyoruz. Büyük projelerde client’a sunacağımız verinin, DB’de işlem yapacağımız veriden farklı, maskelenmiş ve özelleştirilmiş olması gerekir. Örneğin, bir e-ticaret uygulamasında kullanıcı bilgilerini dönen bir endpoint yazdığınızı düşünelim. Güvenlik açısından, kullanıcıların hashlenmiş şifrelerinin, client’a giden veri modelinde bulunmasını istemezsiniz. Kullanıcı bu bilgiyi kullanmasa bile, bu bilginin veri modelinde yer alması bir güvenlik açığı oluşturabilir.

Güvenlik Senaryosu

Bir banka uygulamasında çalıştığınızı varsayalım. Kullanıcıların hesap bilgilerini client’a sunan bir endpoint yazıyorsunuz. Kullanıcının hassas bilgileri, örneğin şifreler veya hesap numaraları, DB’de saklanır ancak client’a gönderilmemesi gerekir. DTO’lar bu noktada devreye girer. DTO’lar, sadece gerekli olan verileri client’a sunmanızı sağlar ve gereksiz veya hassas bilgilerin dışarı çıkmasını engeller. Böylece, bir güvenlik katmanı oluşturmuş olursunuz.

Ayrıca object oriented prensiplerinden abstraction’a da katkı sağlamış olursunuz. Çünkü abstaction’ı arabanın gaz pedalı gibi düşünürseniz kullanıcının sadece gaz pedalını bilmeye ve ona bastığında arabanın gittiğini bilmesine ihtiyacı vardır. Arka tarafındaki motora yakıtı enjekte etme, dişlileri harekete geçirme gibi aksiyonları bilmesine gerek yoktur. Aynı şekilde clientın da DB’deki bilgileri bilmesine gerek yoktur, sadece ihtiyacı olan verileri alması yeterlidir.

Genel olarak bir yazılım geliştirirken, tasarım ihtiyaçlarını analiz edip, servislerin DTO nesne ihtiyaçlarını buna göre belirleriz. Bu ihtiyaçlara uygun DB nesnelerini oluştururken, DTO’da yer almayan bazı özellikler de ekleyebiliriz. Bu özellikler, başka ekranlarda ihtiyaç duyulacak bilgiler veya audit logları için gerekli veriler olabilir.(Audit logları işlemi kimin ne zaman yapıp güncellediği bilgilerini tutan log yapısıdır.) Örneğin tasarıma göre ekranda sadece user tablosundan username ve email gösterilecektir. Ancak telefon numarası bilgisine de ihtiyacımız vardır. Ancak bu bilgiyi user tablosundan çektiğimizde elimizde telefon numarası da olacaktır. Sadece username ve email gösterdiğimiz bir ekran için clienta telefon numarası bilgisini dönmek istemeyiz. İşte bu noktada, DTO kullanımı, daha güvenli, daha hızlı ve daha kolay bakım yapılabilir kodlar geliştirmemize yardımcı olur.

Yukarıda yazdığım avantajlar db objesi ile Presentation katmanı arasında tek bir kere DTO kullanımı için geçerlidir. Ancak bazı durumlarda her katmanın kendisine özel modeli olması istenebilir. Bunun da örneği aşağıdaki gibi olmaktadır:

Yukarıdaki örnekte data kısmında User nesnesi kullanılırken, Service katmanında UserDto nesnesi kullanılmıştır. Presentation aşamasında ise UserResponse nesnesi kullanılmıştır. Burada DTO yu alt katmandan üst katmana veri taşıma objesi olarak tanımladığımızı düşünürsek hem userDto nesnesini hem UserReponse nesnesine DTO diyebiliriz. Bir DTO kullanımı avantajlı ve doğrudur. Ancak her katmanın farklı DTO modelinin olması doğru değildir.

Yukarıdaki ikinci DTO ve AutoMapper kullanımı zaman kaybıdır. Üstelik, DTO’dan entity objelerine geçişi sağlayan AutoMapper veya Mapster gibi araçlar performans kaybına yol açabilir. Diyelim ki yukarıdaki örnekte UserResponse una ihtiyaçtan dolayı bir özellik daha eklememiz gerektiğinde (Email). Bu durumda, üç farklı modele de (User, UserDto, UserResponse) bu özelliği eklemeniz gerekecek. Hatta, eğer isimlendirme açısından DB nesnesi ile kullanıcıya vereceğiniz nesne arasında fark varsa, bir de mapping kütüphanesinde değişiklik yapmanız gerekecek. Bu gerçekten zaman kaybı değil mi? Bu üç katmanda yapılacak güncellemeler ve potansiyel mapping hataları, küçük bir değişikliğin bile büyük bir iş yüküne dönüşmesine neden olabilir.

Peki DTO yu hangi aşamada kullanmalıyız? Bu yazıdaki anlatılan gereklilik presentation katmanı ile data nesnesini ayırmak üzerinedir. Katmanlı mimari için data ve servis katmanlarında data nesnesi kullanılabileceğini, bu aşamada dto ya ihtiyaç olmayacağını düşünüyorum. Ek olarak soğan mimarisinde de presentation katmanı ile domain katmanındaki model izole olmalıdır. domain nesnesi oluşturulduğu taktirde servis ve domain katmanlarında aynı domain modelinin kullanılabileceğini, her katmanda dto kullanımına ihtiyaç olmadığını düşünüyorum. Kendi deneyimlerime göre bu şekilde bir implementasyon hem güvenlik açıklarını kapatır, hem de kod fazlalığından ve mapper ın performans kaybından bizi koruyabilir.

Sonuç olarak, Presentation katmanı ile bir alt katmanı (service katmanı olabilir) arasında DTO ve AutoMapper kullanımı lazımdır. Bunun haricindeki katmanlarda DTO kullanmak birçok durum için zaman ve enerji kaybı olacaktır.

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

Kemal Talha KOÇ
Kemal Talha KOÇ

Written by Kemal Talha KOÇ

I am a software engineer. I am trying to develop easy to maintain, clean, understandable, sustainable codes. I like software and i like to write about it.

No responses yet

Write a response