Mobil ekibiniz bir ürün sayfası geliştiriyor. Genel amaçlı API, telefonun hiç göstermediği onlarca alan döndürüyor; yorumlar, stok ve istek listesi için de ayrı birer çağrı gerekiyor. Bu uç noktalardaki her değişiklik, web sitesine ve üç partnere de hizmet veren bir API ekibini bekliyor.
Backend for frontend (BFF), her istemci deneyimine, istemciyi geliştiren ekibin sahip olduğu küçük bir sunucu tarafı API verir. Bu yazı desenin kökenini, bir BFF'nin neleri yapması gerektiğini, API gateway ve GraphQL ile karşılaştırmasını, OAuth token'larını tarayıcıdan nasıl uzak tuttuğunu, tuzaklarını ve nasıl çizileceğini anlatır.
Desenin kökeni
Deseni SoundCloud adlandırdı. Phil Calçado'nun 2015 tarihli yazısı, herkese açık API üzerine kurulu uygulamaları anlatır: profil sayfası /tracks/1234.json, /tracks/1234/related.json, /users/86762.json ve /users/me.json adreslerini çağırıp sonuçları kendisi birleştiriyordu. İstemci ekipleri kendi backend'lerine sahip olunca birleştirme işini oraya taşıdılar ve uygulama GET /user-profile/123.json istemeye başladı. Terimi web tarafının teknik lideri Nick Fisher türetti. Calçado şöyle özetler: «BFF uygulamanın bir parçasıydı.»
Sam Newman'ın Kasım 2015 tarihli Backends For Frontends makalesi deseni genelleştirdi: her kullanıcı deneyimi için bir backend ve onu o arayüzü geliştiren ekibin bakımı.
Konuşkan istemciler ve herkese uyan tek API
- Konuşkan istemciler. Newman'ın örneği bir istek listesidir: önce liste alınır, sonra öğelerinin adları, fiyatları ve stok durumları. Bu, birbirine bağımlı iki gidiş-dönüş eder; mobil ağda her biri örneğin 150 ms ise, render başlamadan önce 300 ms geçer. BFF ile telefon tek gidiş-dönüş öder, bağımlı çağrılar ise bir sıçramanın en fazla birkaç milisaniye sürdüğü veri merkezinin içinde çalışır.
- En büyük ekrana göre boyutlandırılmış yanıtlar. Telefon hiç göstermediği alanları indirir.
- Ortak darboğaz. Her istemci ekibi değişikliklerini, çoğu zaman ayrı bir ekibe ait tek bir dağıtım birimi için sıraya sokar.
BFF'nin sorumlulukları
| Sorumluluk | BFF'de | BFF'de değil |
|---|---|---|
| Toplama (aggregation) | Ekran başına tek uç nokta, servisleri paralel çağırır | Her istemcinin ihtiyaç duyduğu join'ler; bunlar bir servise aittir |
| Yanıt şekillendirme | Alanları seçmek, yeniden adlandırmak ve biçimlendirmek | Fiyatlandırma gibi iş kuralları |
| Kimlik doğrulama ve oturum | Oturum çerezi, token saklama ve yenileme | Nihai yetkilendirme; kararı servisler verir |
| Önbellek | Kısa ömürlü toplanmış yanıtlar | Yalnızca URL ile anahtarlanan bir önbellekte kişiselleştirilmiş veri |
| Feature flag'ler | Bu istemcinin hangi varyantı gördüğü | Domain davranışını değiştiren flag'ler |
BFF, API gateway ve GraphQL karşılaştırması
| API gateway | BFF | GraphQL sunucusu | |
|---|---|---|---|
| Hizmet verdiği | Tüm istemciler | Tek bir istemci deneyimi | Tek bir şema üzerinden her istemci |
| Genellikle sahibi | Platform ekibi | İstemci ekibi | Bir graph ekibi ya da federasyon yoluyla domain ekipleri |
| Ne yapar | TLS, yönlendirme, token denetimi, hız sınırları | Toplama, şekillendirme, oturum ve token'lar | İstemcilerin alan seçmesini sağlar; resolver'lar servisleri çağırır |
| Ekran değişince değişir mi | Hayır | Evet, aynı sürümde | Çoğu zaman yalnızca sorgu değişir |
| Tipik hata | İş mantığı sızar | Tekrar eden kod, yavaş fan-out | Pahalı sorgular, N+1 resolver çağrıları, daha zor HTTP önbellekleme |
Yaygın bir kurulumda uçta tek bir gateway bulunur ve BFF'ler onun arkasında yer alır; API gateway mimari diyagramı bunun gibidir. Tek bir ortak graph, istemci başına BFF'lerin yerini alabilir; Microsoft'un desen rehberi, frontend'e özel resolver'larla ayrı BFF'lerin bir şey katmayabileceğini belirtir. Bedeli ekip sınırıdır: her istemci ekibi değişiklikleri tek bir şema üzerinde pazarlık eder.
Sahiplik ve ekip sınırları
BFF istemci ekibine aittir: web uygulaması ve BFF'si tek bir pull request'te değişir ve tek bir sürümde yayınlanır. Newman, bir mobil ekibin mağaza incelemesini beklemeden yayın yapmak için mantığı BFF'sine bile taşıyabileceğini belirtir.
Kaç BFF olmalı? Newman, Stewart Gleadow'dan alıntı yapar: bir deneyim, bir BFF. REA Group iOS ve Android için ayrı BFF'ler işletti; SoundCloud iOS ve Android dinleyici uygulamaları arasında tek bir BFF paylaştı ve mühendisleri Newman'a bunu yeniden düşünebileceklerini söyledi. Pete Hodgson'ın yaklaşımı ekip sınırlarını izlemektir. Mühendislik organizasyon şemanız her BFF için tam olarak bir sahip ekip göstermelidir.
Partner BFF'si kararlı, sürümlenmiş bir sözleşme sunar ve servisler değiştikçe bu sözleşmeyi onlara eşler; böylece iç çalışmalar partner entegrasyonlarını bozmaz. Partnerleri doğrudan sürümlenmiş servis API'lerine yönlendirmek de işe yarar.
Tarayıcı uygulamaları için token işleyici olarak BFF
OAuth'u kendisi çalıştıran bir tek sayfa uygulaması token'ları tarayıcıda tutar; enjekte edilen herhangi bir script bunları çalabilir. JWT rehberi, bir tarayıcı uygulamasının token'ları nerede tutabileceğini ve her seçeneğin riskini sıralar. Tarayıcı Tabanlı Uygulamalar için OAuth 2.0 başlıklı RFC 10017, Ağustos 2026'da Best Current Practice (BCP 212) oldu. Üç mimariyi güvenliğin azalan sırasına göre dizer:
| Desen | Token'lar nerede durur | Enjekte edilen JavaScript ne yapabilir | RFC 10017 görüşü |
|---|---|---|---|
| BFF | Yalnızca sunucuda | Sayfa açıkken istekleri BFF üzerinden göndermek | İş ve hassas uygulamalar için şiddetle önerilir |
| Token aracı backend | Access token tarayıcıda, refresh token sunucuda | Access token'ları çalmak ve backend'den yenilerini istemek | Yalnızca tam bir BFF uygulanabilir değilse |
| Tarayıcı tabanlı OAuth istemcisi | Tüm token'lar tarayıcıda | Her token'ı çalmak ve yeni akışlar başlatmak | İş veya hassas uygulamalar için önerilmez |
Burada BFF gizli (confidential) bir OAuth istemcisidir. PKCE ile authorization code akışını çalıştırır, kodu kendi kimlik bilgileriyle takas eder, token'ları kullanıcının oturumuna bağlı olarak saklar ve ilettiği her çağrıya access token'ı ekler. Tarayıcıda yalnızca bir çerez bulunur; OAuth 2.0 akış diyagramı code akışını adım adım gösterir.
RFC'nin ana kuralları:
- Çerez:
SecureveHttpOnlyzorunludur;SameSite=Strict,Path=/,Domainolmaması ve__Host-Http-gibi bir ad öneki önerilir. Chrome ve Firefox bu öneki zorunlu kılar; Safari, bu yazının yazıldığı sırada (Kasım 2026) yalnızca__Host-kısmını uygular. - CSRF: bir savunma zorunludur. Her API çağrısındaki sabit bir özel başlık, farklı kökenli isteklerde CORS preflight'ı zorlar.
- Proxy: yalnızca izin listesindeki sunuculara ilet.
- Oturum durumu: RFC'nin yalnızca küçük ölçekte önerdiği sunucu tarafı bir depo ya da RFC 6265'in tarayıcılardan desteklemesini istediği çerez başına 4.096 bayt sınırı içinde çerezde şifrelenmiş token'lar. Oturumun süresini refresh token'ınki kadar tutun.
Set-Cookie: __Host-Http-sid=3f9c...; Secure; HttpOnly; SameSite=Strict; Path=/
// Same-origin fetch sends the cookie by default.
await fetch("/bff/orders", {
method: "POST",
headers: { "Content-Type": "application/json", "X-CSRF": "1" },
body: JSON.stringify(order),
});
BFF siteler arası betik çalıştırmayı (XSS) engellemez: enjekte edilen kod sayfa açıkken BFF'yi yine çağırabilir, bu yüzden bir Content Security Policy bulundurun. Yerel uygulamalar bunun yerine RFC 8252 kuralını izler ve code akışını PKCE ile sistem tarayıcısında çalıştırır; bu yüzden bir mobil BFF çoğunlukla yalnızca bir bearer token'ı doğrular.
Tuzaklar
- Tekrarlanan mantık. Newman, BFF'leri birbirine bağlayan paylaşılan koda göre bir miktar tekrarı tercih eder. Aynı mantık üçüncü kez ortaya çıktığında onu ayırın: teknik kod için bir kütüphane, iş mantığı için bir domain servisi. SoundCloud, yaklaşık beş BFF'nin her biri kullanıcı profillerini kendi başına oluşturduktan sonra bir UserProfileService yazdı.
- Monolit olarak BFF. Uyarı işaretleri: domain verisine ya da iş kurallarına sahip olması, başka BFF'lerin onu çağırması ya da birkaç ekibin ona commit atması. İndirimi web BFF'nin hesaplayıp mobil BFF'nin hesaplamaması, bir müşterinin bulacağı bir hatadır.
- Fan-out gecikmesi. Bir BFF beş servisi paralel çağırırsa, en az birinin kendi p99 değerinden yavaş yanıt verme olasılığı 1 − 0,99^5 ≈ 4,9% olur: BFF'nin p95'i kabaca servislerin p99'una eşittir. Dean ve Barroso'nun The Tail at Scale yazısı karşı önlemleri anlatır.
- Bir sıçrama daha. Her BFF gecikme, bir dağıtım ve bir nöbet rotasyonu ekler; IP adresine göre hız sınırı uygulayan servisler artık yalnızca BFF'nin adresini görür.
Zaman aşımları, kısmi yanıtlar ve circuit breaker'lar
Ekran başına bir son süre belirleyin ve onu bölüştürün: BFF'de 800 ms varsa, çağrı başına 300 ms zaman aşımı bir yeniden denemeye yer bırakır. Bağımsız çağrıları paralel çalıştırın ve son süreyi aşağıya iletin.
Sonra hangi verinin zorunlu olduğuna karar verin. Newman'ın istek listesi listeye ihtiyaç duyar ama stok durumları olmadan da render edilebilir. Elinizdekini döndürün ve eksik olanı işaretleyin:
{
"items": [{ "id": "sku-123", "name": "Trail shoe", "price": "$89.00" }],
"stock": null,
"errors": [{ "section": "stock", "reason": "timeout" }]
}
Her aşağı akış servisine kendi circuit breaker'ını ve bağlantı havuzunu verin; böylece yavaş bir servis her worker'ı tutmak yerine hızlıca hata verir. Eşikler ve fallback'ler için circuit breaker deseni yazısına bakın. Yalnızca idempotent okumaları, tek bir katmanda yeniden deneyin ve toplanmış yanıtları en taze parçasının izin verdiğinden uzun önbelleğe almayın.
BFF mimari diyagramı
Diyagram içeriği
- Shared services (domain teams)
- Identity provider
- Session store
- Web app
- Web BFF
- Mobile app
- Mobile BFF
- Partner system
- Partner BFF
- Catalog service
- Orders service
- Profile service
- session cookie only
- bearer access token
- client credentials token
- parallel calls + token
- parallel, fewer fields
- stable v1 mapping
- tokens by session ID
- 1. log in (redirect)
- 2. code + PKCE → tokens
Nasıl okunur:
- Her istemci deneyimi için bir satır, sahibi olan ekibe göre renklendirilmiştir. Her istemci yalnızca kendi BFF'sini çağırır.
- Her BFF ortak servislere dağılır; okları çerçevede biter, çünkü ekranlarının ihtiyaç duyduğu hangi servis olursa onu çağırır.
- Kesikli bağlantılar yalnızca oturum açmaya aittir. Tarayıcı kimlik sağlayıcıya yönlendirilir, ardından web BFF kodu token'larla takas eder; bu adım OpenID Connect ile oturum açma akışındakiyle aynıdır.
- Token'lar sunucuda kalır, oturum deposunda bir oturum kimliğinin altında. Şifrelenmiş bir çerez de işe yarar ve RFC 10017 küçük dağıtımların ötesinde onu tercih eder.
- Markdown bloğu çerez ayarlarını ve ekran başına örnek bir süre bütçesini listeler.
BFF diyagramlarını net çizmek
- Her istemciye bir satır verin; BFF'siyle birlikte ve sahip ekibin adıyla etiketleyin.
- Her bağlantıdan geçeni etiketleyin: bir oturum çerezi, bir bearer token ya da istemci kimlik bilgileri.
- Token'ların nerede durduğunu gösterin, bir depoda mı yoksa şifrelenmiş bir çerezde mi.
- Gateway'i ayrı çizin. Gateway ve BFF'ler için tek bir kutu sahipliği gizler.
- Hub'a dikkat edin. Her istemciye bağlı tek bir BFF kutusu, genel amaçlı bir backend'dir.
- Uç nokta listesini atlayın. Her BFF'den bir servis sınırına giden tek bir etiketli bağlantı yeterlidir; servis tarafını BFF'lerin arkasındaki mikroservisleri gösteren bir diyagram ele alır.
Archboard'da oluşturun
- Google veya GitHub ile oturum açın ve bir diyagram oluşturun.
- C4 Modeli paketinden web uygulaması ve mobil uygulama için birer Container ve partner için bir External System ekleyin; her biri ayrı bir satırda olsun.
- Her istemcinin yanına BFF'si için bir Container ekleyin; bir teknoloji ve bir açıklama girin.
- Temel paketinden Shared services (domain teams) adlı bir Çerçeve ekleyin ve içine üç Container node'u koyun: catalog, orders ve profile.
- Web satırının üstüne Güvenlik paketinden bir Kimlik sağlayıcı ve oturum deposu olarak Veri paketinden bir Redis node'u ekleyin.
- Her istemciyi BFF'sine ve her BFF'yi çerçeveye bağlayın, bağlantıları etiketleyin, iki oturum açma bağlantısını kesikli yapın ve her satırı ekibe göre renklendirin.
- Çerez ayarlarını ve bütçeyi içeren bir Temel Markdown bloğu ve ekipler için Temel Metin etiketleri ekleyin.
Servisleriniz zaten bir Mermaid akış şemasında duruyorsa, Mermaid dönüştürücü size düzenlenebilir bir ilk taslak verir. Örnek 13 diagram node kullanıyor ve Free planın sınırları içinde kalıyor.
SSS
Backend for frontend (BFF) deseni nedir? Web uygulaması, mobil uygulama ya da partner entegrasyonu gibi tek bir istemci deneyimi için geliştirilmiş ve o istemcinin ekibine ait bir sunucu tarafı API. Backend çağrılarını toplar ve yanıtları şekillendirir.
BFF ile API gateway arasındaki fark nedir? Gateway tüm istemcilere hizmet verir; yönlendirme, token denetimi ve hız sınırlarını yönetir. BFF tek bir istemciye hizmet verir ve onun ekranlarıyla birlikte değişir. Birçok sistem birkaç BFF'nin önüne bir gateway koyar.
GraphQL, BFF desenini ortadan kaldırır mı? Kaldırabilir, çünkü istemciler ihtiyaç duydukları alanları seçer. Yine de şemanın ve sorgu sınırlarının bir sahibi olmalıdır ve tek bir istemci için kurulmuş bir GraphQL sunucusu başlı başına bir BFF'dir.
BFF kimlik doğrulaması nasıl çalışır? BFF gizli bir OAuth istemcisidir: PKCE ile authorization code akışını çalıştırır, token'ları sunucuda tutar ve tarayıcıya yalnızca HttpOnly bir oturum çerezi verir.
Kaç BFF'im olmalı? Kullanıcı deneyimi başına bir tane, ekiplerinizle hizalı olarak. Aynı deneyime ve aynı sahip ekibe sahip iki uygulama tek bir BFF'yi paylaşabilir.