ERP Entegrasyonu Mimarisi: Senkron, Asenkron ve Olay Tabanlı
ERP entegrasyonu çoğu kurumsal projenin asıl işidir ve en sık burada başarısız olur. Senkron API, asenkron mesaj ve toplu aktarım desenlerini ne zaman seçeceğinizi, anti-corruption layer ile ERP modelini uygulamanızdan nasıl ayıracağınızı ve outbox, idempotency, mutabakat gibi güvenilirlik desenlerini anlatıyoruz.
Kurumsal projelerin çoğunda asıl iş ekranlar değil, ERP entegrasyonudur: stok ve fiyat ERP'den gelecek, sipariş ERP'ye yazılacak, müşteri kartı iki sistemde de aynı olacak. Projelerin en sık takıldığı yer de burasıdır — çünkü entegrasyon bir "bağlantı" değil, iki sistemin farklı veri modelleri, farklı zamanlamaları ve farklı arıza davranışları arasında kurulan bir sözleşmedir.
Bu yazıda ERP entegrasyonunu üç temel soru üzerinden tasarlamayı, senkron, asenkron ve toplu aktarım desenlerinin hangi veri için doğru olduğunu, ERP modelini uygulamanızdan ayıran anti-corruption layer'ı ve üretimde ayakta kalmayı sağlayan güvenilirlik desenlerini anlatıyoruz. Örnekler SAP terminolojisiyle verilse de yaklaşım Logo, Netsis, Microsoft Dynamics veya herhangi bir ERP için aynıdır.
Her veri akışı için üç soru
Entegrasyon şemasına çizgi çekmeden önce her veri akışı için üç soruya yazılı cevap veriyoruz:
Veri yönü ve sahiplik: Bu verinin doğrusu hangi sistemde? Müşteri kartı ERP'de doğuyorsa uygulama onu kopyalar, düzenlemez. Sipariş uygulamada doğuyorsa ERP alıcıdır. Çift yönlü sahiplik en pahalı senaryodur ve mümkünse tasarımla ortadan kaldırılır.
Zamanlama: Cevap anında mı gerekiyor (stok sorgusu), dakikalar içinde yeterli mi (sipariş aktarımı), gecelik mi (ürün kataloğu)? Zamanlama toleransı deseni belirler.
Arıza davranışı: ERP yanıt vermezse ne olur? Kullanıcı bekler mi, işlem kuyruğa alınır mı, son bilinen değerle devam mı edilir? Bu sorunun cevabı yoksa entegrasyon ilk ERP bakımında ekranı kilitler.
Üç desen: senkron, asenkron, toplu
Desen | Teknoloji | Uygun veri | Güçlü yanı | Riski |
|---|---|---|---|---|
Senkron istek–yanıt | REST / OData, RFC-BAPI, SOAP | Anlık stok, fiyat, kredi limiti sorgusu | Her zaman güncel cevap | ERP'nin erişilebilirliğine ve yanıt süresine bağımlılık; kota sınırları |
Asenkron mesaj | Kuyruk (Kafka, RabbitMQ), IDoc, outbox tablosu | Sipariş, fatura, teslimat gibi işlemsel kayıtlar | ERP kapalıyken de kayıt kaybolmaz; yeniden denenebilir | Sıralama, tekrar teslim, "işlendi mi" sorusu |
Toplu / delta aktarım | Zamanlanmış iş, dosya, değişiklik damgası (watermark) | Ürün kataloğu, müşteri kartı, fiyat listesi | Basit, hacme dayanıklı, ERP'yi yormaz | Gecikme; delta mantığı yanlışsa eksik kayıt |
Gerçek projelerde üçü birlikte kullanılır: katalog gecelik toplu, stok anlık senkron, sipariş asenkron. Tek desene zorlamak — her şeyi senkron ya da her şeyi Kafka — entegrasyonların en yaygın tasarım hatasıdır.
Anti-corruption layer: ERP modeli uygulamaya sızmasın
ERP'nin veri modeli onlarca yıllık kararların ürünüdür: MATNR, KUNNR, 18 haneli sıfır dolgulu numaralar, kod tabloları. Bu model doğrudan uygulamanızın entity'lerine girerse uygulama ERP'nin bir uzantısına dönüşür ve ERP değiştiğinde (sürüm, yeni sistem, şirket birleşmesi) her şey değişir. Çözüm, DDD literatüründeki adıyla anti-corruption layer: entegrasyon katmanı ERP'yle kendi diliyle konuşur, uygulamaya kendi modeliyle döner.
// Uygulamanın kendi sözleşmesi — ERP'den bağımsız
public interface StokKaynagi {
Optional<StokDurumu> sorgula(UrunKodu urun, DepoKodu depo);
}
// SAP adaptörü — ERP'nin dilini burada konuşuruz, dışarı sızdırmayız
@Component
class SapStokAdaptoru implements StokKaynagi {
private final SapOdataClient client;
@Override
@CircuitBreaker(name = "sap", fallbackMethod = "sonBilinen")
@TimeLimiter(name = "sap")
public Optional<StokDurumu> sorgula(UrunKodu urun, DepoKodu depo) {
var r = client.get("/API_MATERIAL_STOCK_SRV/A_MatlStkInAcctMod",
Map.of("Material", urun.sapFormat(), "Plant", depo.value()));
return r.map(SapStokEsleme::toStokDurumu); // MATNR → UrunKodu, MENGE → miktar
}
Optional<StokDurumu> sonBilinen(UrunKodu urun, DepoKodu depo, Throwable t) {
return stokOnbellek.sonDeger(urun, depo); // ERP kapalıysa: son bilinen değer + "eski" işareti
}
}Bu katmanın iki görevi vardır: eşleme (kod tabloları, formatlar, birimler) ve yalıtım (timeout, circuit breaker, fallback). ERP'nin yanıt vermediği durumda kullanıcıya "son bilinen stok, 12 dakika önce" göstermek, boş ekran ve 30 saniyelik beklemeden iyidir.
Asenkron yazmada güvenilirlik: outbox, idempotency, DLQ
Siparişin ERP'ye yazılması en kritik akıştır ve üç garantiyi birlikte ister: sipariş kaydedildiyse ERP'ye mutlaka gitmeli (kayıp yok), iki kez gitse bile ERP'de iki sipariş oluşmamalı (tekrar yok), gidemediyse birinin haberi olmalı (sessizlik yok).
1. Outbox: kayıt ile mesaj aynı transaction'da
@Transactional
public SiparisNo olustur(SiparisTalebi talep) {
Siparis s = siparisRepository.save(Siparis.from(talep));
outboxRepository.save(OutboxKaydi.of( // aynı transaction: ya ikisi ya hiçbiri
"SIPARIS_OLUSTURULDU", s.getNo().value(), SapSiparisMesaji.from(s)));
return s.getNo();
}
@Scheduled(fixedDelay = 2_000)
void outboxuBosalt() {
for (OutboxKaydi k : outboxRepository.bekleyenler(100)) {
try {
sapClient.siparisOlustur(k.payload(), k.idempotencyKey()); // key = sipariş no
k.tamamlandi();
} catch (GeciciHata e) {
k.ertele(backoff(k.denemeSayisi())); // 1dk, 5dk, 30dk...
} catch (KaliciHata e) {
k.olumKuyruguna(e.getMessage()); // DLQ: insan müdahalesi
}
}
}Outbox tablosu mesaj kuyruğunun yerini almak zorunda değildir; Kafka kullanıyorsanız outbox'tan Kafka'ya, oradan ERP adaptörüne akar. Kritik nokta, iş kaydı ile "gönderilecek" kaydının aynı transaction'da yazılmasıdır.
2. Idempotency: aynı mesaj iki kez, tek etki
Yeniden deneme olan her yerde tekrar teslim vardır. ERP tarafında sipariş numarası ya da bir idempotency anahtarı "daha önce işlendi mi" kontrolüyle eşlenmelidir; SAP'de bu genellikle harici referans alanı (örneğin satış siparişinde müşteri referansı) ile yapılır. Anahtar yoksa ilk ağ kesintisinde ERP'de çift sipariş oluşur.
3. Görünürlük ve mutabakat
Her outbox kaydının durumu (bekliyor, gönderildi, hata, DLQ) bir panelde görünmelidir; "sessizce duran entegrasyon" en tehlikeli entegrasyondur. Buna ek olarak gecelik bir mutabakat işi, uygulamadaki siparişlerle ERP'deki siparişleri karşılaştırır ve farkları raporlar. Mutabakat, tüm diğer önlemler doğru çalışsa bile kalan tek güvenlik ağıdır.
SAP özelinde arayüz seçimi
OData API'leri (S/4HANA): Senkron sorgular ve basit yazmalar için standart yol; API Business Hub'da dokümante, yetkilendirmesi net.
RFC / BAPI (JCo): Standart API'nin kapsamadığı işlemler ve eski ECC sistemleri için; performansı yüksek, ama bağlantı yönetimi ve sürüm bağımlılığı sizin sorumluluğunuzda.
IDoc: Asenkron toplu belge aktarımının SAP-yerlisi; sipariş, fatura, sevkiyat için olgun ve izlenebilir.
SAP CPI: Çok sistemli senaryolarda eşleme ve yönlendirmeyi merkeze alan ara katman; küçük entegrasyonlarda ek maliyet, büyük peyzajlarda düzen.
Bu seçeneklerin Java tarafından kullanımını ayrı bir yazıda ayrıntılı ele alacağız; burada kural şudur: standart API varken özel RFC yazmayın, ve hangi arayüzü seçerseniz seçin anti-corruption layer'ın arkasında kalsın.
Sık yapılan altı hata
ERP veritabanına doğrudan yazmak. İş kurallarını atlar, garanti dışıdır, ilk sürüm güncellemesinde kırılır.
ERP modelini uygulamaya taşımak. Uygulama entity'sinde
MATNRalanı görüyorsanız sınır yoktur.Senkron zincir. Kullanıcı isteği → uygulama → ERP → başka sistem; her halka gecikme ve arıza olasılığı ekler.
Yeniden deneme var, idempotency yok. Çift sipariş, çift fatura.
Sessiz entegrasyon. Hata logu var, izleyen yok; farkına varan muhasebe olur.
Mutabakat yok. Fark oluştuğunda ne zaman ve neden oluştuğu bilinmez.
Tasarım kontrol listesi
Her veri akışı için sahip sistem, zamanlama toleransı ve arıza davranışı yazılı.
Katalog/master veri toplu, sorgular senkron, işlemsel kayıtlar asenkron olarak ayrıştırıldı.
ERP adaptörü uygulamanın kendi arayüzünün arkasında; eşleme tek yerde.
Senkron çağrılarda timeout, circuit breaker ve fallback tanımlı.
Asenkron yazmalarda outbox, backoff'lu retry, DLQ ve idempotency anahtarı var.
Her mesajın durumu bir panelde görünür; gecelik mutabakat işi kurulu.
Test ortamında ERP'nin sandbox'ı ya da sözleşme testleri (contract test) mevcut.
Sık sorulan sorular
Kafka olmadan güvenilir ERP entegrasyonu kurulabilir mi?
Evet. Outbox tablosu + zamanlanmış gönderici, orta hacimli çoğu kurumsal senaryo için yeterlidir ve operasyon yükü çok daha düşüktür. Kafka; çok tüketicili, yüksek hacimli veya olay tabanlı geniş bir peyzaj varsa anlamlıdır.
ERP'de değişen veriyi nasıl yakalarız?
Tercih sırası: ERP'nin kendi olay/webhook mekanizması, değişiklik damgasına (son güncelleme tarihi) dayalı delta sorgusu, en son çare olarak tam karşılaştırma. Doğrudan veritabanı trigger'ı ERP tedarikçisinin desteği dışındadır.
Entegrasyon ne kadar sürer?
API'si dokümante bir ERP'ye tek yönlü bir akış birkaç haftadır; çift yönlü, çok nesneli, eski sistemli senaryolar aylar sürer. Süreyi belirleyen kod değil, ERP tarafındaki erişim, yetki ve test verisinin hazır olma hızıdır.
Sonuç
ERP entegrasyonu, doğru deseni doğru veriye uygulamak ve arıza anını baştan tasarlamaktır: sorgular senkron ama yalıtılmış, kayıtlar asenkron ama garantili, master veri toplu ama delta. ERP modelini bir adaptörün arkasında tutan ve her mesajın durumunu gösteren bir entegrasyon, ERP değişse bile ayakta kalır.
Mevcut sistemlerinizi birbirine bağlamak ya da sessizce duran bir entegrasyonu izlenebilir hale getirmek için entegrasyon ve otomasyon ile SAP danışmanlığı hizmetlerimize göz atabilirsiniz. Keşif görüşmesi ve ilk tahmin ücretsizdir.