Blog
Mert Özen'in yazılım geliştirme, backend, frontend ve DevOps üzerine blog yazıları.
Go'da HTTP Client: http.Client, Timeout'lar, context ile İptal, Transport'u Yeniden Kullanmak ve Retry
Go'da http.DefaultClient'ın timeout'u yoktur; üretimde paylaşılan tek bir http.Client, her aşama için Transport timeout'ları, deneme başına Client.Timeout ve toplam bütçe için context kullanılır. Hangi timeout'un hangi aşamayı kapsadığı, Go 1.27'nin küçük body'leri Close'ta okuyup bağlantıyı geri kazanması, MaxIdleConnsPerHost, 4xx/5xx kontrolü, backoff, jitter ve Retry-After ile retry, idempotency ve httptest ile client testi.
Go'da io.Reader/io.Writer, os ve bufio: Dosya İşlemleri, Stream Kompozisyonu ve embed
Go'da dosya, gzip, HTTP body ve string aynı tek method'luk io.Reader'ı karşılar; fonksiyon dosya adı yerine io.Reader alırsa 1 GB'lık log sabit bellekle işlenir. bufio.Scanner'ın 64 KB satır sınırı ve sessiz durması, yazılan dosyada Close hatası, csv.Writer'ı flush etmek, LimitReader/MultiWriter/TeeReader ile kompozisyon ve e-posta şablonunu //go:embed ile binary'ye gömmek.
Go'da slices, maps, sort ve cmp Paketleri: Sıralama, Arama, Gruplama ve Iterator'larla Collection İşleri
Go'da çok alanlı sıralama slices.SortStableFunc ile cmp.Or ve cmp.Compare'ın birleşimidir; map iterasyon sırası her çalıştırmada değişir, sıralı key'ler için slices.Sorted(maps.Keys(m)) gerekir. Bookstore'a ?sort= ve kategori özeti, LINQ karşılıkları, append ve slices.Delete ile backing array tuzakları, json/v2'nin map sırası, sort ile slices ölçümü ve x/text/collate ile Türkçe sıralama.
Go'da time Paketi: time.Time, Duration, Referans Zamanla Format ("2006-01-02"), Time Zone ve Monotonic Clock
Go'da tarih biçimi yyyy-MM-dd gibi kodlarla değil, referans zaman 2006-01-02 15:04:05'in nasıl yazılacağı gösterilerek verilir; "yyyy-MM-dd" hata vermez, olduğu gibi yazılır. Duration, json/v2'nin Duration'a varsayılan biçim vermemesi, time zone'lar ve 11'deki üç saatlik kayma, scratch image'da ve Windows'ta time/tzdata, depo saatine göre teslim tahmini, monotonic clock ile Equal ve time.After tuzağı.
Go'da String'lerle Çalışmak: strings, strconv, fmt Verb'leri, byte/rune Farkı ve Türkçe Karakterler
Go'da string değiştirilemeyen bir UTF-8 byte dizisidir ve strings package'ı dile bakmaz: strings.EqualFold "istanbul" ile "İSTANBUL"u eşit saymaz, Türkçe kurallar için unicode.TurkishCase gerekir. ISBN normalize edip doğrulamak, strconv hata tipleri, Türkçe biçimli fiyat okumak, fmt verb'leri ve go vet, strings.Builder ölçümü ve RE2 tabanlı regexp.
Go 1.22'den 1.27'ye: Loop Variable, Routing, range-over-func, Green Tea GC, json/v2 ve Generic Method'lar
Go'da bir sürümün davranışını go.mod'daki go satırı ve GODEBUG ayarları belirler; ama kaldırılan ayarlar bu korumayı bitirir: Go 1.27 asynctimerchan'ı kaldırdığı için go 1.22 diyen bir module'ün timer davranışı sadece toolchain yükseltilerek değişti. 1.22'den 1.27'ye backend için önemli değişiklikler, nil check düzeltmesi, os.Root, uuid, yeni allocator ölçümü, json/v2'ye geçişin istemcilere etkisi ve go fix modernizer'ları.
Go Servisini Production'a Taşımak: slog, Configuration, Graceful Shutdown, pprof ve Küçük Container
Bir Go servisini production'a hazırlamak için ayarları ortam değişkenlerinden bir struct'a okumak, log/slog ile JSON log yazmak, SIGTERM'i signal.NotifyContext ile yakalayıp server.Shutdown ile kapanmak, health check eklemek ve pprof'u ayrı port'ta açmak gerekir. Bookstore'da request ID'li slog, drain süresi, container-aware GOMAXPROCS ve GOMEMLIMIT ölçümü, -trimpath ve ldflags ile build, 4,72 MB'lık distroless image.
Go'da Test: testing Paketi, Table-Driven Test, httptest, Benchmark ve synctest
Go'da test için framework kurulmaz: _test.go dosyaları, t.Run ile table-driven test, interface'i karşılayan elle yazılmış fake'ler ve httptest yeter. Bookstore'da stok kuralının tablo testi, sabit saat, mux üzerinden handler testi, Go 1.27'nin httptest.NewTestServer'ı ile synctest, negatif tutar hatasını bulan fuzz testi, generic kodun benchmark'ı, SQL Server'a giden entegrasyon testi, coverage ve go test -race.
Go'dan SQL Server ve PostgreSQL'e: database/sql, go-mssqldb, Connection Pool, Transaction ve sqlc
Go'da veritabanına database/sql ile bağlanılır: sql.Open bir connection değil connection pool döndürür, driver blank import ile kaydolur, sipariş ve stok düşümü BeginTx, defer Rollback ve Commit ile tek transaction'da yapılır. Bookstore'un siparişleri go-mssqldb ile SQL Server'da: pool ayarları, koşullu UPDATE ile lost update'i önlemek, Scanner/Valuer ile decimal'dan kuruşa, rows.Close sızıntısı, datetime2 saat dilimi tuzağı, pgx ve sqlc'nin SQL Server durumu.
Go'da JSON ve Request Validation: encoding/json, json/v2, Struct Tag'leri ve Body Sınırları
Go'da bir JSON body'yi güvenle okumak için Content-Type, MaxBytesReader ile boyut sınırı, DisallowUnknownFields ve tek değer kontrolü gerekir; encoding/json v1 ise alan adlarını büyük/küçük harfe bakmadan eşleştirip tekrar eden alanda sonuncuyu alır. Bookstore'da POST /api/orders, *int ile eksik değer, errors.Join ağacından validation listesi, ASP.NET Core ile aynı sözleşmede Problem Details, Go 1.27'nin json/v2 farkları ve fiyatı float64 yerine kuruşla taşımak.
net/http ile HTTP Server: ServeMux Pattern Routing, Handler, Middleware ve Timeout'lar
Go'da bir HTTP servisi için standart kütüphane yeterli: ServeMux 1.22'den beri method ve wildcard pattern'lerini en spesifik olan kazanır kuralıyla eşliyor, middleware ise bir handler'ı saran sıradan bir fonksiyon. Bookstore API'sinin httpapi package'ına taşınması, RequestID ve Logging middleware'leri, CORS ve CrossOriginProtection, 307 redirect, pattern çakışması panic'i, WriteTimeout'un handler'ı durdurmaması ve slowloris'e karşı http.Server timeout'ları.
Go'da Concurrency Pattern'leri: context, sync, errgroup, Worker Pool ve Goroutine Leak
Go'da eşzamanlı erişilen veri ya bir mutex ile korunur ya da bir channel ile sahibine bırakılır; korunmayan map process'i çökertir, korunmayan sayaç ise sessizce aynı sipariş ID'sini üretir. Bookstore'da concurrent map writes ve race detector, Service ile memstore'un mutex ile düzeltilmesi, context ile iptal ve deadline, WaitGroup.Go, errgroup ile 10.000 faturalık worker pool, Go 1.27'nin goroutineleak profili ve synctest ile 15 dakikalık testi anında çalıştırmak.