İçeriğe Atla
Mustafa Erbay
Teknoloji · 12 dk okuma · görüntülenme

API Tasarımında 3 Yaklaşım: REST, GraphQL ve gRPC Karşılaştırması

REST, GraphQL ve gRPC API tasarım yaklaşımlarını derinlemesine inceleyerek, hangi senaryoda hangisinin daha uygun olduğunu somut örneklerle karşılaştırıyorum.

100%

API Tasarımında Yol Ayrımı: REST, GraphQL ve gRPC

Bu sabah masama otururken aklıma takılan bir konu vardı: API’lerimizi tasarlarken hangi yolu izlemeliyiz? Özellikle son yıllarda karşımıza çıkan farklı yaklaşımlar, doğru seçimi yapmayı bazen zorlaştırabiliyor. Üretim ERP’miz üzerinde çalışırken veya kendi yan ürünlerimin backend’ini geliştirirken sürekli olarak bu sorularla karşılaştım. REST, yıllardır standart olagelmişken, GraphQL ve gRPC gibi daha yeni oyuncular da sahneye çıktı. Bu yazıda, bu üç popüler API tasarım yaklaşımını derinlemesine inceleyecek, avantajlarını, dezavantajlarını ve hangi durumlarda tercih edilmesi gerektiğini somut örneklerle masaya yatıracağım. Hedefim, bu karşılaştırma sonucunda kendi projeleriniz için en doğru kararı vermenize yardımcı olmak.

API’ler, modern yazılım mimarilerinin bel kemiğini oluşturur. Farklı servislerin, uygulamaların ve hatta cihazların birbiriyle konuşmasını sağlarlar. Bu iletişimin ne kadar verimli, ölçeklenebilir ve yönetilebilir olacağı ise büyük ölçüde seçtiğimiz API tasarım yaklaşımına bağlıdır. Yanlış bir seçim, performans sorunlarından geliştirme süreçlerinin yavaşlamasına kadar birçok probleme yol açabilir. Gelin, bu yol ayrımındaki üç ana seçeneği mercek altına alalım.

REST: Web’in Weyl’i ve Neden Hala Güçlü?

REST (Representational State Transfer), web servisleri için geliştirilmiş bir mimari stildir. 2000’lerin başında Roy Fielding tarafından tanımlanan prensipleri, bugün hala birçok uygulamanın temelini oluşturuyor. REST’in en büyük gücü, HTTP protokolünün standartlarını (GET, POST, PUT, DELETE gibi metodlar) ve URL’leri kullanarak kaynaklara erişim sağlamasıdır. Bu durum, onu oldukça anlaşılır ve yaygın hale getiriyor.

REST’in temelinde kaynak odaklılık yatar. Her şey bir kaynaktır ve bu kaynaklara standart HTTP metodlarıyla müdahale edilir. Örneğin, bir kullanıcı listesi GET /users ile alınır, yeni bir kullanıcı POST /users ile oluşturulur, belirli bir kullanıcı GET /users/{id} ile getirilir, güncellenir PUT /users/{id} ile ve silinir DELETE /users/{id} ile. Bu basit ve tutarlı yapı, özellikle yeni başlayanlar için öğrenme eğrisini düşürür.

Ancak REST’in en çok eleştirilen yönlerinden biri, “over-fetching” (gereğinden fazla veri çekme) ve “under-fetching” (gereğinden az veri çekme) sorunlarıdır. Bir istemci, ihtiyacı olmayan birçok alanı içeren bir yanıt alabilir (over-fetching) ya da tek bir işlem için birden fazla API çağrısı yapmak zorunda kalabilir (under-fetching). Örneğin, bir kullanıcı profili görmek istediğinizde, profil resmi, adı, soyadı gibi temel bilgilerle birlikte, o ana kadar yaptığı tüm yorumların listesi de dönebilir. Eğer sadece adını ve soyadını istiyorsanız, bu gereksiz veri trafiğine yol açar. Kendi yan ürünüm olan finansal hesaplayıcılarının backend’ini tasarlarken, müşteri bilgileri çekilirken bazen gereksiz yere tüm iletişim bilgilerinin de dönmesi performansı olumsuz etkiliyordu. Bu durumu düzeltmek için endpoint’leri daha spesifik hale getirmek gerekiyordu, ki bu da endpoint sayısını artırıyordu.

// Örnek GET /users/{id} yanıtı (over-fetching senaryosu)
{
  "id": 123,
  "name": "Mustafa",
  "surname": "Erbay",
  "email": "[email protected]",
  "phone": "+905xxxxxxxxx",
  "address": "Ankara, Türkiye",
  "createdAt": "2023-01-15T10:00:00Z",
  "updatedAt": "2024-05-20T14:30:00Z",
  "comments": [ // Bu veri belki de istenmiyordu
    {"id": 1, "text": "Harika bir yazı."},
    {"id": 2, "text": "Teknik detaylar çok iyi."}
  ]
}

REST’in bir diğer özelliği de durum bilgisiz (stateless) olmasıdır. Sunucu, her isteği bağımsız olarak ele alır ve istemcinin önceki istekleri hakkında herhangi bir bilgi saklamaz. Bu, ölçeklenebilirliği artırır çünkü herhangi bir sunucu, herhangi bir istemci isteğini işleyebilir. Ancak, oturum yönetimi gibi durum gerektiren senaryolarda ek mekanizmalar (örneğin token tabanlı kimlik doğrulama) kullanmak gerekir.

REST’in Avantajları ve Dezavantajları

REST’in hala popüler olmasının ardında yatan nedenler oldukça açık:

  • Basitlik ve Anlaşılırlık: HTTP’nin standartlarını kullanması sayesinde öğrenmesi ve uygulaması kolaydır.
  • Yaygınlık ve Ekosistem: Neredeyse tüm diller ve framework’ler için bolca kütüphane ve araç desteği bulunur.
  • Durum Bilgisizlik (Statelessness): Ölçeklenebilirliği kolaylaştırır.
  • Önbelleğe Alma (Caching): HTTP önbelleğe alma mekanizmalarından faydalanabilir.

Ancak bazı dezavantajları da göz ardı edilemez:

  • Over-fetching ve Under-fetching: İstemcinin tam olarak ihtiyacı olan veriyi almakta zorlanması ve birden fazla istek yapma ihtiyacı.
  • Esneklik Eksikliği: İstemci ve sunucu arasındaki kontratın katı olması, değişiklik yapmayı zorlaştırabilir.
  • Performans: Özellikle mobil cihazlar veya bant genişliği kısıtlı ağlarda gereksiz veri trafiği sorun yaratabilir.

Bu dezavantajlar, özellikle mobil uygulamalar veya karmaşık veri gereksinimleri olan frontend uygulamaları için GraphQL gibi alternatiflerin doğmasına zemin hazırladı.

GraphQL: İstemcinin Gücü ve Esnekliği

GraphQL, Facebook tarafından geliştirilen ve 2015’te açık kaynak olarak yayınlanan bir sorgu dilidir. REST’in aksine, GraphQL istemcilere tam olarak ihtiyaç duydukları veriyi talep etme imkanı sunar. Sunucu, istemcinin isteğine göre şekillenen yanıtlar döner. Bu, “over-fetching” ve “under-fetching” sorunlarını ortadan kaldırmayı hedefler.

GraphQL ile bir istemci, hangi alanlara ihtiyacı olduğunu açıkça belirten bir sorgu gönderir. Sunucu ise bu sorguyu yorumlayarak sadece istenen verileri içeren bir JSON yanıtı döner. Bu yaklaşım, özellikle mobil uygulamalar için büyük bir avantajdır. Bant genişliği kısıtlı olduğunda veya pil ömrünü optimize etmek istediğinizde, sadece ihtiyacınız olan veriyi çekmek performansı önemli ölçüde artırır. Kendi geliştirdiğim Android spam engelleyici uygulamamda, sunucuyla iletişim kurarken sadece gerekli kullanıcı bilgilerini çekebilmek, uygulamanın daha hızlı yanıt vermesini sağlıyordu.

GraphQL’in temelinde şema (schema) yatar. Bu şema, API’nizdeki tüm veri türlerini, alanları ve ilişkileri tanımlar. Bu, hem geliştiricilere API’nin neler sunabildiğini anlamaları için bir rehber görevi görür hem de hataları geliştirme aşamasında yakalamayı kolaylaştırır. GraphQL sunucusuna gönderilen her sorgu, bu şemaya göre doğrulanır.

# Örnek GraphQL sorgusu
query GetUserAndComments($userId: ID!) {
  user(id: $userId) {
    name
    surname
    comments(first: 5) { # Sadece ilk 5 yorumu isteyelim
      text
      createdAt
    }
  }
}

GraphQL, tek bir endpoint (/graphql) üzerinden çalışır. Tüm sorgular, POST isteğiyle bu endpoint’e gönderilir. Bu, REST’in birden fazla endpoint yönetme karmaşıklığını ortadan kaldırır. Ancak, bu durum önbelleğe alma (caching) stratejilerini biraz daha karmaşık hale getirebilir, çünkü HTTP metodları burada belirleyici rol oynamaz.

GraphQL’in Avantajları ve Dezavantajları

GraphQL’in sunduğu esneklik, onu birçok modern uygulama için cazip kılsa da bazı zorlukları da beraberinde getirir:

  • Esnek Veri Çekme: İstemciler tam olarak ihtiyaç duydukları veriyi talep edebilir, over-fetching ve under-fetching sorunları ortadan kalkar.
  • Tek Endpoint: Yönetimi kolaylaştırır.
  • Güçlü Tip Sistemi: Şema, API’yi daha öngörülebilir hale getirir ve geliştirme hatalarını azaltır.
  • Geliştirici Deneyimi: Özellikle frontend geliştiricileri için veri alımını kolaylaştırır.

Bununla birlikte, bazı dezavantajları da vardır:

  • Öğrenme Eğrisi: REST’e göre daha karmaşıktır ve özel bir altyapı gerektirir.
  • Caching Karmaşıklığı: HTTP önbellekleme mekanizmaları doğrudan uygulanamaz, özel çözümler gerekir.
  • Performans Optimizasyonu: Karmaşık sorgular sunucu tarafında yoğun kaynak tüketimine yol açabilir. Örneğin, bir sorgu yüzlerce veritabanı sorgusu tetikleyebilir. Bu, “N+1 query problem”i olarak da bilinir ve dikkatli yönetilmezse ciddi performans sorunlarına neden olabilir.
  • Dosya Yükleme: GraphQL’in dosya yükleme için standart bir yöntemi yoktur; genellikle REST veya özel çözümlerle entegre edilmesi gerekir.

GraphQL, özellikle karmaşık veri grafikleri olan ve istemci tarafında büyük esneklik gerektiren uygulamalar için harika bir seçenektir. Ancak, basit CRUD (Create, Read, Update, Delete) işlemleri için veya basit bir API’ye ihtiyacınız varsa, GraphQL’in getirdiği karmaşıklık gereksiz olabilir.

gRPC: Performans Odaklı, Protokol Tabanlı İletişim

gRPC (gRPC Remote Procedure Calls), Google tarafından geliştirilen ve açık kaynaklı bir uzaktan prosedür çağrısı (RPC) çerçevesidir. REST ve GraphQL’in aksine, gRPC HTTP/1.1 yerine HTTP/2 protokolünü kullanır. Bu, onu daha performanslı, verimli ve düşük gecikmeli hale getirir. gRPC, özellikle servisler arası (service-to-service) iletişimde öne çıkar.

gRPC’nin temelinde Protocol Buffers (Protobuf) yatar. Protobuf, verilerin serileştirilmesi için kullanılan, dil ve platformdan bağımsız, genişletilebilir bir mekanizmadır. API’nizdeki servisleri ve mesaj yapılarını .proto dosyalarında tanımlarsınız. Bu dosyalar, gRPC araçları tarafından çeşitli programlama dilleri için kod üretmek amacıyla kullanılır. Bu otomatik kod üretimi, veri serileştirme/deserileştirme işlemini optimize eder ve geliştirme süreçlerini hızlandırır. Üretim ERP’si üzerinde çalışırken, farklı modüller arasında veri aktarımı için gRPC kullanmak, veri dönüşümlerini basitleştirmiş ve hızlandırmıştı.

gRPC, HTTP/2’nin özelliklerinden tam olarak yararlanır:

  • Çoklama (Multiplexing): Tek bir TCP bağlantısı üzerinden birden fazla isteğin aynı anda iletilmesini sağlar. Bu, bağlantı başına düşen gecikmeyi azaltır.
  • İstek/Yanıt Akışları (Streams): Tek yönlü (sunucudan istemciye veya istemciden sunucuya) veya çift yönlü (bidirectional) veri akışlarını destekler. Bu, gerçek zamanlı iletişim senaryoları için idealdir.
  • Başlık Sıkıştırma (Header Compression): HTTP/2, başlıkları sıkıştırarak ağ trafiğini azaltır.

gRPC, öncelikli olarak ikili (binary) veri formatı kullanır. Bu, metin tabanlı JSON’a göre daha kompakttır ve daha hızlı işlenir. Bu özellikler, gRPC’yi yüksek performans gerektiren, düşük gecikmenin kritik olduğu ve servisler arası yoğun iletişimin olduğu mikroservis mimarilerinde popüler bir seçim haline getirir.

// Örnek .proto dosyası
syntax = "proto3";

service UserService {
  rpc GetUser (GetUserRequest) returns (User);
  rpc CreateUser (CreateUserRequest) returns (User);
}

message GetUserRequest {
  string user_id = 1;
}

message CreateUserRequest {
  string name = 1;
  string email = 2;
}

message User {
  string id = 1;
  string name = 2;
  string email = 3;
  string created_at = 4;
}

gRPC’nin Avantajları ve Dezavantajları

gRPC, özellikle performans ve verimlilik arayanlar için güçlü bir seçenektir:

  • Yüksek Performans: HTTP/2 ve Protobuf kullanımı sayesinde çok hızlıdır ve düşük gecikme sunar.
  • Verimlilik: İkili veri formatı ve başlık sıkıştırma ile ağ trafiğini azaltır.
  • Güçlü Tip Sistemi ve Kod Üretimi: Protobuf, dil ve platformdan bağımsız kod üretimi ile geliştirme süreçlerini kolaylaştırır ve hataları azaltır.
  • Akış Desteği: Gerçek zamanlı ve çift yönlü iletişim için idealdir.
  • Servisler Arası İletişim: Mikroservis mimarilerinde tercih edilen bir çözümdür.

Ancak gRPC’nin de bazı sınırlamaları vardır:

  • Tarayıcı Desteği: Doğrudan tarayıcılar tarafından desteklenmez. Tarayıcıdan gRPC kullanmak için gRPC-Web gibi ek çözümler gereklidir. Bu, REST’in tarayıcıdaki doğal üstünlüğüne karşı bir dezavantajdır.
  • Karmaşıklık: Öğrenme eğrisi REST’e göre daha diktir.
  • İnsan Tarafından Okunabilirlik: İkili veri formatı, REST’in JSON’una göre insanlar tarafından okunması ve hata ayıklaması daha zordur.
  • Araç Desteği: REST kadar geniş ve standart bir araç ekosistemine henüz sahip değildir.

gRPC, özellikle sunucu-sunucu iletişimi, mikroservisler arası haberleşme ve gerçek zamanlı veri akışları gerektiren senaryolarda mükemmel bir seçimdir. Ancak, doğrudan tarayıcıdan erişim gereken durumlar için REST veya GraphQL daha uygun olabilir.

Karşılaştırma Tablosu ve Hangi Durumda Hangisi?

Bu üç yaklaşımı özetlemek ve karar verme sürecini kolaylaştırmak için bir karşılaştırma tablosu oluşturalım:

Özellik REST GraphQL gRPC
Protokol HTTP/1.1, HTTP/2 HTTP/1.1, HTTP/2 HTTP/2
Veri Formatı JSON, XML JSON Protobuf (Binary)
İstek Yöntemi Kaynak odaklı (URL + HTTP Metodu) Sorgu odaklı (Tek endpoint) RPC odaklı (Servis + Metod)
Veri Çekme Over/Under-fetching riski İstemci kontrollü, esnek Sabit yanıt yapısı (protobuftan gelir)
Önbellekleme Kolay (HTTP caching) Karmaşık (Özel çözümler gerekir) Karmaşık (HTTP/2 caching sınırlı)
Tarayıcı Desteği Doğal Doğal (bazı sınırlamalarla) Yok (gRPC-Web ile mümkündür)
Performans Orta İyi (sunucu yükü iyi yönetilmeli) Çok İyi (düşük gecikme, yüksek verim)
Geliştirme Kolaylığı Yüksek Orta (öğrenme eğrisi var) Orta (protobuflar ve RPC konsepti var)
Uygulama Alanı Genel amaçlı API’ler, halka açık API’ler Karmaşık veri grafikleri, mobil uygulamalar Mikroservisler, servisler arası iletişim
Örnek Kullanım E-ticaret siteleri, blog API’leri Sosyal medya platformları, Dashboard’lar İç servisler, oyun sunucuları, IoT cihazları

Peki, bu bilgiler ışığında hangi teknoloji sizin için doğru?

  • REST’i Seçin Eğer:

    • Basit CRUD operasyonlarına sahip bir API’ye ihtiyacınız varsa.
    • Halka açık bir API tasarlıyorsanız ve geniş uyumluluk istiyorsanız.
    • Tarayıcı tabanlı uygulamalar geliştiriyorsanız ve basit bir entegrasyon arıyorsanız.
    • Ekibiniz REST’e zaten hakimse ve hızlıca geliştirmeye başlamak istiyorsanız.
    • Önbellekleme mekanizmalarını kolayca kullanmak istiyorsanız.
  • GraphQL’i Seçin Eğer:

    • Frontend ekibiniz belirli veri parçalarına ihtiyacı olan karmaşık sorgular yapıyorsa.
    • Mobil uygulamalar geliştiriyorsanız ve bant genişliğini optimize etmek istiyorsanız.
    • API’nizin evrimleşmesi gerekiyorsa ve istemcilerin farklı veri setleri talep etmesi bekleniyorsa.
    • API’nizin veri grafiği karmaşıksa ve ilişkili verileri tek bir istekte çekmek istiyorsanız.
  • gRPC’yi Seçin Eğer:

    • Mikroservis mimarisi kullanıyorsanız ve servisler arası iletişimi optimize etmek istiyorsanız.
    • Yüksek performans, düşük gecikme ve yüksek veri akışı kritikse.
    • Gerçek zamanlı veri akışı veya çift yönlü iletişim gerektiren uygulamalar geliştiriyorsanız.
    • Tarayıcı tabanlı uygulamalar için gRPC-Web gibi ek teknolojiler kullanmaya hazırsanız.
    • Dil ve platform bağımsız, güçlü tip kontrollü bir iletişim katmanı istiyorsanız.

Sonuç: Seçim Sizin, Ama Bilinçli Yapın

API tasarımı, yazılım mimarisinin en kritik kararlarından biridir. REST, yıllardır süregelen hakimiyetiyle hala geçerli bir seçenek olsa da, GraphQL ve gRPC gibi yenilikçi yaklaşımlar, belirli senaryolarda çok daha üstün çözümler sunabiliyor. REST’in basitliği ve yaygınlığı, GraphQL’in esnekliği ve istemci odaklılığı, gRPC’nin ise saf performansı ve verimliliği öne çıkar.

Bu yazıda, her bir yaklaşımın temel prensiplerini, avantajlarını, dezavantajlarını ve pratik kullanım alanlarını inceledik. Kendi projelerimde yaşadığım deneyimler ve karşılaştığım zorluklar üzerinden somut örnekler vermeye çalıştım. Unutmayın ki en iyi teknoloji, sizin özel ihtiyaçlarınıza en uygun olanıdır. Bu karşılaştırmanın, projeniz için doğru API tasarım yaklaşımını seçmenize yardımcı olacağını umuyorum.

Bu konudaki deneyimlerinizi veya sorularınızı yorumlarda paylaşmaktan çekinmeyin. Belki de bir sonraki yazımda, sizin sorduğunuz bir sorunun cevabını veya karşılaştığınız bir sorunu ele alırım.

Paylaş:

Bu yazı faydalı oldu mu?

Yükleniyor...

Bu yazı nasıldı?

Sıkça Sorulanlar

Bu makale ile ilgili okurların sorduğu yaygın sorular.

Yeni bir ERP modülü geliştirirken REST, GraphQL ve gRPC arasında nasıl bir seçim yapmalıyım?
Veri yapısının sabit olduğu ve CRUD işlemlerinin ağırlıklı olduğu bir senaryo için REST'i tercih etmek mantıklı; çünkü ekipler HTTP metodlarını genelde iyi bilir ve Swagger dokümantasyonu hızlıca oluşturulabilir. Raporlama ekranı gibi çoklu ilişkilere sahip ve istemcinin sadece ihtiyacı olan alanları çekmek istediği bir özellik için GraphQL'e geçmek anlamlı olabilir; Apollo Server kurulumu kısa sürede tamamlanır ve veri aşırı çekimini büyük ölçüde azaltır. Gerçek zamanlı bildirimler ve düşük gecikme gerektiren mikroservis iletişimi için ise gRPC öne çıkar; protobuf tanımlarıyla tip güvenliği sağlanır ve servisler arası gecikme belirgin biçimde düşer.
GraphQL'in REST'e göre performans ve veri aşırı çekimi (over‑fetching) konusundaki avantajları ve dezavantajları nelerdir?
GraphQL devreye alındığında, istemcilerin sadece ihtiyaç duydukları alanları sorgulaması ağ trafiğini belirgin biçimde azaltabilir; bu özellikle mobil cihazlarda hissedilir bir fayda sağlar. Ancak, sorgu karmaşıklığı arttıkça sunucu tarafında resolver zincirleri uzar ve N+1 problemini ortaya çıkarabilir; bu sorun DataLoader ile hafifletilebilir ama ek bir katman ekler. REST ise basit endpoint'lerle önceden tanımlı veri setlerini döndürdüğü için cache mekanizmaları (CDN, HTTP cache) daha etkili çalışıyor. Özetle, GraphQL esnekliği ve veri israfını önler, ama sorgu optimizasyonu ve cache yönetimi ekstra çaba gerektiriyor.
gRPC streaming kullanırken karşılaştığım hatayı nasıl çözdüm ve hangi araçları kullandım?
Ben bir mikroservis arasında gerçek zamanlı veri akışı kurarken, istemcide "UNAVAILABLE" hatası aldım; sorunun protokol versiyon uyumsuzluğundan kaynaklandığını bulmak zor oldu. İlk adımda, `grpcurl` ile servis tanımını doğrudan sorguladım ve method imzasının farklı olduğunu fark ettim. Ardından, protobuf dosyalarını tek bir ortak repo içinde tutmaya başladım ve CI pipeline'ına `protoc` derleme adımı ekledim. Sorunu izlemek için `Jaeger` tracing ve `Prometheus` metriklerini entegre ettim; böylece akış gecikmesini ve paket kaybını anlık izleyebildim. Sonuçta, versiyon senkronizasyonu ve izleme araçları hatanın hızlı çözülmesini sağladı.
REST'in artık eski ve kullanılmaz olduğu yönündeki genel kanı doğru mu?
REST'in tamamen modası geçmiş olduğu iddiası aşırı genelleştirilmiş. Büyük ölçekli bir ERP platformunda REST endpoint'leriyle uzun yıllar boyunca yoğun işlem yürütülebilir; HTTP cache, stateless mimari ve geniş topluluk desteği yüksek kararlılık sağlar. Elbette, çok dinamik istemci ihtiyaçları ve gerçek zamanlı senaryolar için GraphQL veya gRPC daha uygun olabilir, ama REST hâlâ basit CRUD, dış sistem entegrasyonu ve hızlı prototipleme için güçlü bir temel sunuyor. Dolayısıyla, teknoloji seçiminde iş gereksinimi ve ekip yetkinliği belirleyici olmalı, REST'i tamamen reddetmek yerine doğru bağlamda kullanmak daha akıllıca.
ME

Mustafa Erbay

Sistem Mimarisi · Network Uzmanı · Altyapı, Güvenlik ve Yazılım

2006'dan bu yana sistem mimarisi, network, sunucu altyapıları, büyük yapıların kurulumu, yazılım ve sistem güvenliği ekseninde çalışıyorum. Bu blogda sahada karşılığı olan teknik deneyimlerimi paylaşıyorum.

Kişisel Notlar

Bu notlar sadece sizde saklanır. Tarayıcınızda yerel olarak tutulur.

Hazır 0 karakter

Yorumlar

Sunucu Taraflı AI Moderasyon

Yorumlar sunucuda yapay zeka ile denetlenir ve kalıcı olarak saklanır.

?
0/2000

Sunucu taraflı AI denetim

✉️ Ücretsiz · Spam yok · İstediğin an çık

Yeni yazılardan haberdar olun

Yeni içerikler ve teknik notlar e-postanıza gelsin.

  • 📌
    Haftanın en iyisi Sadece okumaya değer tek yazı
  • 🔧
    Alet çantası Bu hafta kullandığım araçlar
  • 🧠
    Perde arkası Blog'a girmeyen notlar

Spam yapmıyoruz. İstediğiniz zaman ayrılabilirsiniz. · Sadece Umami (self-hosted, Google yok) ile takip.

Okuma İstatistikleriniz

0

Yazı Okundu

0dk

Okuma Süresi

0

Gün Serisi

-

Favori Kategori

İlgili Yazılar