Silgi'de Paylaşılan Yardımcılar (Shared)
Silgi'nin en güçlü özelliklerinden biri, shared
sistemi aracılığıyla servislerin ortak fonksiyonlara ve verilere erişimini sağlayan paylaşılan yardımcılardır. Paylaşılan yardımcılar, kodunuzu daha modüler hale getirir, tekrarı azaltır ve bakımı kolaylaştırır.
Neden Paylaşılan Yardımcılar Kullanmalıyım?
- Kod Tekrarını Azaltma: Yaygın işlevleri bir kez tanımlayın, tüm servislerinizde kullanın.
- Tutarlılık: İş mantığınızın merkezileştirilmesiyle tutarlı davranış sağlayın.
- Modülerlik: Karmaşık işlevleri daha küçük, yeniden kullanılabilir parçalara bölerek tasarım kalitesini artırın.
- Verimlilik: Veritabanı bağlantıları gibi kaynakları paylaşarak performansı optimize edin.
- Test Edilebilirlik: Paylaşılan mantık birimlerini daha kolay izole edip test edin.
- İşbirliği: Ekip üyeleri arasında kod paylaşımını kolaylaştırın.
- Modüller Arası İletişim: Farklı modüller arasında veri ve işlev paylaşımını kolaylaştırın.
Paylaşılan Yardımcı Temelleri
createShared
Fonksiyonu
createShared
, paylaşılan yardımcılar oluşturmak için ana yapı taşıdır. Bu fonksiyon, servislere erişilebilir olacak işlev ve değerlerin bir koleksiyonunu tanımlar.
Temel Yapı:
import { createShared } from 'silgi'
import type { ExtendShared } from 'silgi/types'
export interface TarihYardimcisi extends ExtendShared {
// Tip tanımlarınız burada
formatTarih: (tarih: Date) => string
tarihAraligi: (baslangic: Date, bitis: Date) => number
}
export const tarihYardimcisi = createShared({
// Uygulamanız burada
formatTarih: (tarih) => { /* ... */ },
tarihAraligi: (baslangic, bitis) => { /* ... */ }
})
ExtendShared
Arayüzü
ExtendShared
, paylaşılan yardımcılarınız için bir taban tip sağlayan özel bir arayüzdür. Tüm paylaşılan yardımcı arayüzleriniz bu arayüzden türetilmelidir.
Neden ExtendShared
kullanmalıyız?
- CLI Entegrasyonu: Silgi CLI, paylaşılan yardımcılarınızı otomatik olarak tanır ve bağlar.
- Tip Genişletme: Silgi'nin dahili tiplerini kendi paylaşılan yardımcı tiplerinizle genişletir.
- Tutarlılık: Tüm paylaşılan yardımcıların ortak bir taban tipine sahip olmasını sağlar.
- Modül Entegrasyonu: Modüllerin paylaşılan yardımcılara yeni özellikleri güvenli bir şekilde eklemelerine olanak tanır.
Adım Adım Paylaşılan Yardımcı Oluşturma
1. Paylaşılan Yardımcı Dosyası Oluşturma
Tipik olarak, paylaşılan yardımcılarınızı serverDir
dizininde isteğiniz bir yerde oluşturabilirsiniz. Servislerinizin içinde de olabilirler. CLI otomatik hepsini bulacaktır.
import { createShared } from 'silgi'
import type { ExtendShared } from 'silgi/types'
// Tip tanımı
export interface TarihYardimcisi extends ExtendShared {
formatTarih: (tarih: Date) => string
gunFarki: (baslangic: Date, bitis: Date) => number
}
// İşlev uygulamaları
function formatTarih(tarih: Date): string {
return tarih.toISOString().split('T')[0]
}
function gunFarki(baslangic: Date, bitis: Date): number {
const farkMs = bitis.getTime() - baslangic.getTime()
return Math.floor(farkMs / (1000 * 60 * 60 * 24))
}
// Paylaşılan yardımcı oluşturma
export const tarihYardimcisi = createShared({
formatTarih,
gunFarki,
})
Dikkat
Export edilen paylaşılan yardımcılarınızın export const
ve export interface
ile başlaması gerekmektedir. Aksi takdirde Silgi CLI bu yardımcıyı bulamaz.
2. Değişiklikleri Hazırlama
Paylaşılan yardımcılarınızı tanımladıktan sonra, Silgi'nin bunları taraması ve bağlaması için:
pnpm silgi prepare
komutunu çalıştırın.
3. Servislerde Paylaşılan Yardımcılara Erişme
Artık tüm servis handler'larınızda bu paylaşılan yardımcılara otomatik olarak erişebilirsiniz:
import { createService } from 'silgi'
export const siparisService = createService({
eticaret: {
siparis: {
get: {
detay: {
handler: async (input, shared) => {
// Paylaşılan yardımcıya erişim
const siparisKayit = /* siparişi veritabanından çek */
const simdikiTarih = new Date()
const teslimTarihi = new Date(siparisKayit.teslimTarihi)
const kacGunKaldi = shared.tarihYardimcisi.gunFarki(simdikiTarih, teslimTarihi)
return {
...siparisKayit,
teslimTarihiFormatli: shared.tarihYardimcisi.formatTarih(teslimTarihi),
kacGunKaldi
}
}
}
}
}
}
})
Daha Gelişmiş Senaryolar
Veritabanı İşlemleri İçin Paylaşılan Yardımcılar
Veritabanı istemcilerini veya diğer harici kaynakları paylaşmak yaygın bir senaryodur:
import { createShared } from 'silgi'
import type { ExtendShared } from 'silgi/types'
import { createClient } from 'veritabani-kutuphanesi'
export interface VeritabaniYardimcisi extends ExtendShared {
kullaniciGetir: (id: string) => Promise<any>
siparisGetir: (id: string) => Promise<any>
dbIstemci: ReturnType<typeof createClient>
}
// İstemciyi bir kez oluştur (bağlantı havuzu)
const dbIstemci = createClient({
connectionString: process.env.DATABASE_URL
})
export const veritabaniYardimcisi = createShared({
// Yüksek seviye sorgular
kullaniciGetir: (id) => {
return dbIstemci.query('SELECT * FROM kullanicilar WHERE id = $1', [id])
},
siparisGetir: (id) => {
return dbIstemci.query('SELECT * FROM siparisler WHERE id = $1', [id])
},
// Ham istemciye erişim
dbIstemci,
})
Konfigürasyon ve Ortam Değişkenlerine Erişim
Paylaşılan yardımcılar ayrıca konfigürasyon değerlerine erişmek için de kullanılabilir:
import { createShared } from 'silgi'
import type { ExtendShared } from 'silgi/types'
import { useSilgiRuntimeConfig } from 'silgi/runtime'
export interface KonfigurasyonYardimcisi extends ExtendShared {
apiAnahtariGetir: () => string
tabanUrlGetir: () => string
}
export const konfigurasyonYardimcisi = createShared({
apiAnahtariGetir: () => {
const config = useSilgiRuntimeConfig()
return config.database.apiKey || 'varsayilan-anahtar'
},
tabanUrlGetir: () => {
const config = useSilgiRuntimeConfig()
const ortam = process.env.NODE_ENV
return ortam === 'production' ? config.database.prodUrl : config.database.devUrl
}
})
Dışa Bağımlı Servisler için İstemciler
Dış API'lere istemciler oluşturmak için de paylaşılan yardımcılar kullanabilirsiniz:
import { createShared } from 'silgi'
import type { ExtendShared } from 'silgi/types'
import { odemeIstemcisiOlustur } from '../utils/odeme'
export interface OdemeYardimcisi extends ExtendShared {
odemeBaslat: (tutar: number, kartBilgisi: any) => Promise<any>
odemeIptalEt: (islemId: string) => Promise<boolean>
}
// İstemciyi bir kez oluştur
const odemeIstemcisi = odemeIstemcisiOlustur({
apiKey: process.env.ODEME_API_KEY,
gateway: 'iyzico'
})
export const odemeYardimcisi = createShared({
odemeBaslat: (tutar, kartBilgisi) => {
return odemeIstemcisi.islemOlustur({ tutar, kart: kartBilgisi })
},
odemeIptalEt: (islemId) => {
return odemeIstemcisi.islemIptalEt(islemId)
}
})
shared
Nesnesinin İçeriği
Bir servis handler'ında shared
parametresi aşağıdakilere erişim sağlar:
- Özel Paylaşılan Yardımcılar: Sizin tanımladığınız tüm paylaşılan yardımcılar (ör.
shared.tarihYardimcisi
,shared.veritabaniYardimcisi
). - Storage (Depolama): Key-value depolama sistemlerine erişim (ör.
shared.storage('bellek').setItem('anahtar', 'değer')
). - Runtime Config: Çalışma zamanı yapılandırmasına erişim (ör.
shared.runtimeConfig.ozelModul.ayar
). - Framework Context: Altta yatan framework'ün bağlamına erişim.
Örnek kullanım:
handler: async (input, shared) => {
// Özel paylaşılan yardımcılar
const kullanici = await shared.veritabaniYardimcisi.kullaniciGetir(input.kullaniciId)
// Storage kullanımı
await shared.storage('onbellek').setItem(`kullanici:${kullanici.id}`, kullanici, { ttl: 3600 })
// Runtime Config erişimi
const apiAnahtari = shared.runtimeConfig.hariciApi.apiKey
return { /* sonuç */ }
}
Paylaşılan Yardımcılarda En İyi Uygulamalar
- Tek Sorumluluk İlkesi: Her paylaşılan yardımcıyı belirli bir amaç için tasarlayın (ör.
veritabaniYardimcisi
,logYardimcisi
,onbellekYardimcisi
). - Tip Tanımları: Mümkün olduğunca tam tip tanımlamaları kullanın.
any
kullanımından kaçının. - Dokümantasyon: İşlevlerinizi JSDoc ile belgelendirin.
- İlklendirilme Yönetimi: Ağır kaynakları (veritabanı bağlantıları gibi) sadece bir kez oluşturun.
- Temiz Hatalar: Özel hata türlerini veya
ErrorFactory
'yi kullanarak anlamlı hatalar fırlatın. - Test Edilebilirlik: Paylaşılan yardımcılarınızı test edebilmeniz için modüler tasarlayın.
Sıkça Sorulan Sorular
Farklı Ortamlar İçin Paylaşılan Yardımcıları Nasıl Ayarlarım?
Ortama bağlı davranış için koşullu mantık kullanabilirsiniz:
export const veritabaniYardimcisi = createShared({
baglantiKur: () => {
const ortam = process.env.NODE_ENV
if (ortam === 'test') {
return testVeritabaninasBaglan()
}
return uretimVeritabaninaBaglan()
}
})
Paylaşılan Yardımcılara Servislerin Dışında Nasıl Erişim Sağlayabilirim?
Özel durumlarda, paylaşılan yardımcılara runtime içinden doğrudan erişebilirsiniz:
import { shareds } from './server/silgi/scan'
export async function hariciIslem() {
const shared = shareds()
// Paylaşılan yardımcıya erişim
return shared.veritabaniYardimcisi.siparisGetir('123')
}
Ancak bu yaklaşım mümkünse servisler içinde kullanılmalı ve harici erişim sınırlandırılmalıdır.
Özet
Silgi'de paylaşılan yardımcılar, kodunuzu daha modüler, daha bakımı kolay ve yeniden kullanılabilir hale getiren güçlü bir mekanizmadır. createShared
ve ExtendShared
ile tanımlanan bu yardımcılar, servisleriniz arasında veritabanı bağlantıları, yardımcı işlevler, konfigürasyon değerleri ve çok daha fazlasını paylaşmanıza olanak tanır.
Her şeyi en iyi şekilde yapmanın yolu, mantığınızı paylaşılan yardımcılara çıkarmak ve servisleri mümkün olduğunca ince tutmaktır. Bu, kodunuzu daha kolay test etmenizi ve bakımını yapmanızı sağlar.
Gelişmiş Örnek: İlgili Ürünler Servisi
Aşağıda, birden fazla paylaşılan yardımcıyı kullanan daha gelişmiş bir servis örneği bulabilirsiniz:
import { createService, ErrorFactory } from 'silgi'
export const urunService = createService({
eticaret: {
urun: {
get: {
ilgiliUrunler: {
handler: async (input, shared) => {
shared.logYardimcisi.bilgiKaydet(`İlgili ürünler getiriliyor: ${input.parameters.urunId}`)
// Ana ürünü getir
const urun = await shared.veritabaniYardimcisi.urunGetir(input.parameters.urunId)
if (!urun) {
throw ErrorFactory.notFound('Ürün bulunamadı')
}
// Önbellekte ilgili ürünleri ara
const onbellekAnahtari = `ilgiliUrunler:${urun.id}`
const onbelleklenmisUrunler = await shared.storage('redis').getItem(onbellekAnahtari)
if (onbelleklenmisUrunler) {
shared.logYardimcisi.bilgiKaydet('İlgili ürünler önbellekten alındı')
return onbelleklenmisUrunler
}
// AI servisini kullan
const ilgiliUrunIds = await shared.yapayZekaYardimcisi.ilgiliUrunleriBul({
urunId: urun.id,
kategori: urun.kategori
})
// İlgili ürünleri getir
const ilgiliUrunler = await Promise.all(
ilgiliUrunIds.map(id => shared.veritabaniYardimcisi.urunGetir(id))
)
// Sonuçları önbelleğe al
await shared.storage('redis').setItem(onbellekAnahtari, ilgiliUrunler, {
ttl: 60 * 60 // 1 saat
})
// Metrik kaydet
shared.metrikYardimcisi.sayacArtir('ilgili_urunler_bulundu', ilgiliUrunler.length)
return ilgiliUrunler
}
}
}
}
}
})
Bu örnekte birden fazla anlamlı isimlendirilmiş paylaşılan yardımcı kullanılmaktadır:
- veritabaniYardimcisi: Veritabanı işlemleri için
- logYardimcisi: Loglama ve formatlamalar için
- storage: Redis önbellekleme için
- yapayZekaYardimcisi: İlgili ürünler bulma için yapay zeka servisi
- metrikYardimcisi: Performans ve kullanım metrikleri için
Bu yapı, servis kodunu temiz tutarken karmaşık işlemleri paylaşılan yardımcılara havale ederek modülerlik ve yeniden kullanılabilirlik sağlar.