{"id":39438,"date":"2026-02-21T13:40:51","date_gmt":"2026-02-21T10:40:51","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/?p=39438"},"modified":"2026-02-21T13:40:51","modified_gmt":"2026-02-21T10:40:51","slug":"angularda-redux-tarzi-durum-yonetimi-icin-ngrx-ile-baslangic","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/angularda-redux-tarzi-durum-yonetimi-icin-ngrx-ile-baslangic\/","title":{"rendered":"Angular&#8217;da Redux Tarz\u0131 Durum Y\u00f6netimi i\u00e7in ngrx ile Ba\u015flang\u0131\u00e7"},"content":{"rendered":"<p><body><\/p>\n<h2>Angular&#8217;da Redux Tarz\u0131 Durum Y\u00f6netimi i\u00e7in ngrx ile Ba\u015flang\u0131\u00e7<\/h2>\n<p>Angular, b\u00fcy\u00fck ve karma\u015f\u0131k kurumsal uygulamalar geli\u015ftirmek i\u00e7in g\u00fc\u00e7l\u00fc bir \u00e7er\u00e7evedir. Ancak, uygulama b\u00fcy\u00fcd\u00fck\u00e7e ve bile\u015fenler aras\u0131 ileti\u015fim karma\u015f\u0131kla\u015ft\u0131k\u00e7a, durum y\u00f6netimi (state management) \u00f6nemli bir zorluk haline gelebilir. Verilerin farkl\u0131 bile\u015fenler aras\u0131nda senkronize edilmesi, g\u00fcncellenmesi ve tutarl\u0131 bir \u015fekilde korunmas\u0131, \u00f6zellikle \u00e7ok say\u0131da bile\u015fenin ayn\u0131 verilere eri\u015fmesi veya bu verileri de\u011fi\u015ftirmesi gerekti\u011finde, geli\u015ftiriciler i\u00e7in ba\u015f a\u011fr\u0131s\u0131 yaratabilir. \u0130\u015fte bu noktada, Redux mimarisi ve onun Angular i\u00e7in adaptasyonu olan ngrx devreye girer.<\/p>\n<p>Bu makalede, ngrx&#8217;in ne oldu\u011funu, neden kullan\u0131lmas\u0131 gerekti\u011fini, temel prensiplerini ve Angular uygulamalar\u0131n\u0131zda Redux tarz\u0131 durum y\u00f6netimini nas\u0131l uygulayaca\u011f\u0131n\u0131z\u0131 ad\u0131m ad\u0131m inceleyece\u011fiz. Basit bir saya\u00e7 uygulamas\u0131 \u00f6rne\u011fi \u00fczerinden ngrx&#8217;in ana bile\u015fenleri olan Store, Actions, Reducers, Selectors ve Effects&#8217;i derinlemesine ele alaca\u011f\u0131z. Amac\u0131m\u0131z, ngrx&#8217;e yeni ba\u015flayanlar i\u00e7in kapsaml\u0131 bir rehber sunmak ve bu g\u00fc\u00e7l\u00fc k\u00fct\u00fcphaneyi Angular projelerinize entegre etme konusunda size yol g\u00f6stermektir.<\/p>\n<h3>Durum Y\u00f6netimi Neden \u00d6nemlidir?<\/h3>\n<p>Modern tek sayfa uygulamalar\u0131nda (SPA&#8217;lar), kullan\u0131c\u0131 aray\u00fcz\u00fc ve arkas\u0131ndaki veri aras\u0131nda s\u00fcrekli bir etkile\u015fim vard\u0131r. Bir kullan\u0131c\u0131 bir d\u00fc\u011fmeye t\u0131klad\u0131\u011f\u0131nda, bir form g\u00f6nderdi\u011finde veya bir liste \u00f6\u011fesi se\u00e7ti\u011finde, uygulaman\u0131n durumu de\u011fi\u015fir. Bu de\u011fi\u015fiklikler, uygulaman\u0131n farkl\u0131 b\u00f6l\u00fcmlerinde yans\u0131t\u0131lmal\u0131 ve tutarl\u0131l\u0131k sa\u011flanmal\u0131d\u0131r.<\/p>\n<p>Geleneksel olarak, Angular&#8217;da durum y\u00f6netimi i\u00e7in <code>@Input()<\/code> ve <code>@Output()<\/code> dekorat\u00f6rleri arac\u0131l\u0131\u011f\u0131yla bile\u015fenler aras\u0131 ileti\u015fim, servisler arac\u0131l\u0131\u011f\u0131yla veri payla\u015f\u0131m\u0131 veya RxJS Subject&#8217;ler kullan\u0131lm\u0131\u015ft\u0131r. Ancak, uygulama hiyerar\u015fisi derinle\u015ftik\u00e7e ve bile\u015fenler aras\u0131 ba\u011f\u0131ml\u0131l\u0131klar artt\u0131k\u00e7a:<\/p>\n<p>*   <strong>Veri Ak\u0131\u015f\u0131 Karma\u015f\u0131kla\u015f\u0131r:<\/strong> Hangi verinin nerede g\u00fcncellendi\u011fini takip etmek zorla\u015f\u0131r.<br \/>\n*   <strong>Hata Ay\u0131klama Zorla\u015f\u0131r:<\/strong> Bir hatan\u0131n kayna\u011f\u0131n\u0131 bulmak, durumun hangi noktada tutars\u0131z hale geldi\u011fini anlamak g\u00fc\u00e7le\u015fir.<br \/>\n*   <strong>Performans Sorunlar\u0131 Ortaya \u00c7\u0131kabilir:<\/strong> Gereksiz g\u00fcncellemeler veya veri kopyalamalar\u0131 performans\u0131 etkileyebilir.<br \/>\n*   <strong>Kod Tekrar\u0131 Artar:<\/strong> Ayn\u0131 veriyi y\u00f6netmek i\u00e7in farkl\u0131 bile\u015fenlerde benzer kodlar yaz\u0131labilir.<\/p>\n<p>Bu sorunlar\u0131 \u00e7\u00f6zmek i\u00e7in Redux gibi \u00f6ng\u00f6r\u00fclebilir durum y\u00f6netimi yakla\u015f\u0131mlar\u0131 geli\u015ftirilmi\u015ftir.<\/p>\n<h3>Redux Prensipleri ve ngrx&#8217;in Yeri<\/h3>\n<p>Redux, JavaScript uygulamalar\u0131 i\u00e7in tahmin edilebilir durum kapsay\u0131c\u0131s\u0131d\u0131r. Temelde \u00fc\u00e7 ana prensibe dayan\u0131r:<\/p>\n<p>1.  <strong>Tek Do\u011fruluk Kayna\u011f\u0131 (Single Source of Truth):<\/strong> Uygulaman\u0131z\u0131n t\u00fcm durumu tek bir b\u00fcy\u00fck JavaScript nesnesinde saklan\u0131r. Bu nesneye &#8220;Store&#8221; ad\u0131 verilir.<br \/>\n2.  <strong>Durum Salt Okunurdur (State is Read-Only):<\/strong> Durum do\u011frudan de\u011fi\u015ftirilemez. Durumu de\u011fi\u015ftirmek i\u00e7in tek yol, bir &#8220;Action&#8221; ad\u0131 verilen olay\u0131 g\u00f6ndermektir. Bu, durum de\u011fi\u015fikliklerinin izlenebilir ve \u00f6ng\u00f6r\u00fclebilir olmas\u0131n\u0131 sa\u011flar.<br \/>\n3.  <strong>De\u011fi\u015fiklikler Saf Fonksiyonlarla Yap\u0131l\u0131r (Changes are Made with Pure Functions):<\/strong> Durumu de\u011fi\u015ftiren fonksiyonlara &#8220;Reducers&#8221; denir. Reducers, mevcut durumu ve bir action&#8217;\u0131 girdi olarak al\u0131r ve yeni bir durumu \u00e7\u0131kt\u0131 olarak d\u00f6nd\u00fcr\u00fcr. Yan etkilere (side effects) neden olmazlar ve her zaman ayn\u0131 girdi i\u00e7in ayn\u0131 \u00e7\u0131kt\u0131y\u0131 \u00fcretirler.<\/p>\n<p>ngrx, Redux prensiplerini Angular ekosistemine ta\u015f\u0131yan bir k\u00fct\u00fcphane koleksiyonudur. RxJS&#8217;in g\u00fcc\u00fcnden yararlanarak, Angular uygulamalar\u0131nda reaktif ve tahmin edilebilir bir durum y\u00f6netimi \u00e7\u00f6z\u00fcm\u00fc sunar. ngrx, sadece <code>Store<\/code> mod\u00fcl\u00fcnden ibaret de\u011fildir; ayn\u0131 zamanda <code>Effects<\/code> (yan etkileri y\u00f6netmek i\u00e7in), <code>Selectors<\/code> (durumdan veri se\u00e7mek i\u00e7in), <code>Entity<\/code> (koleksiyonlar\u0131 y\u00f6netmek i\u00e7in) ve <code>Schematics<\/code> (boilerplate kodunu azaltmak i\u00e7in) gibi ek mod\u00fclleri de i\u00e7erir.<\/p>\n<h3>ngrx Mimarisi ve Bile\u015fenleri<\/h3>\n<p>ngrx, belirli bir veri ak\u0131\u015f\u0131 ve bile\u015fenler aras\u0131 etkile\u015fim modeli sunar. Temel bile\u015fenleri \u015funlard\u0131r:<\/p>\n<p>*   <strong>Store:<\/strong> Uygulaman\u0131n durumunu tutan merkezi depodur. Bile\u015fenler bu depodan durumu okur ve action&#8217;lar g\u00f6ndererek durumu de\u011fi\u015ftirir.<br \/>\n*   <strong>Actions:<\/strong> Uygulamada meydana gelen benzersiz olaylar\u0131 tan\u0131mlayan basit nesnelerdir. \u00d6rne\u011fin, bir kullan\u0131c\u0131n\u0131n &#8220;\u00fcr\u00fcn ekle&#8221; d\u00fc\u011fmesine t\u0131klamas\u0131 bir action&#8217;\u0131 tetikleyebilir. Action&#8217;lar genellikle bir <code>type<\/code> \u00f6zelli\u011fine ve iste\u011fe ba\u011fl\u0131 olarak bir <code>payload<\/code> (action ile birlikte ta\u015f\u0131nan veri) \u00f6zelli\u011fine sahiptir.<br \/>\n*   <strong>Reducers:<\/strong> Action&#8217;lar\u0131 dinleyen ve uygulaman\u0131n durumunu de\u011fi\u015ftiren saf fonksiyonlard\u0131r. Mevcut durumu ve tetiklenen action&#8217;\u0131 girdi olarak al\u0131r, yeni bir durum nesnesi d\u00f6nd\u00fcr\u00fcr. Reducers asla mevcut durumu do\u011frudan mutasyona u\u011fratmaz; her zaman yeni bir durum nesnesi d\u00f6nd\u00fcr\u00fcr.<br \/>\n*   <strong>Selectors:<\/strong> Store&#8217;daki durumdan belirli veri par\u00e7alar\u0131n\u0131 se\u00e7mek i\u00e7in kullan\u0131lan saf fonksiyonlard\u0131r. Performans optimizasyonu i\u00e7in memoization (belle\u011fe alma) \u00f6zelliklidirler, yani ayn\u0131 girdi i\u00e7in daha \u00f6nce hesaplanm\u0131\u015f sonucu d\u00f6nd\u00fcr\u00fcrler.<br \/>\n*   <strong>Effects:<\/strong> Uygulaman\u0131n d\u0131\u015f d\u00fcnyayla etkile\u015fimini (API \u00e7a\u011fr\u0131lar\u0131, router navigasyonlar\u0131, veritaban\u0131 i\u015flemleri vb.) y\u00f6neten yan etkilerdir. Reducers&#8217;\u0131n saf kalmas\u0131n\u0131 sa\u011flarlar ve asenkron i\u015flemleri y\u00f6netmek i\u00e7in RxJS operat\u00f6rlerini kullan\u0131rlar.<br \/>\n*   <strong>Schematics:<\/strong> Angular CLI ile entegre olarak ngrx kod iskeletini otomatik olarak olu\u015fturmaya yarayan ara\u00e7lard\u0131r. Bu sayede boilerplate kodu azalt\u0131l\u0131r ve geli\u015ftirme h\u0131z\u0131 art\u0131r\u0131l\u0131r.<\/p>\n<h3>ngrx Kurulumu ve Temel Kullan\u0131m<\/h3>\n<p>ngrx&#8217;i kullanmaya ba\u015flamak i\u00e7in \u00f6ncelikle bir Angular projesine ihtiyac\u0131m\u0131z var.<\/p>\n<h4>Proje Olu\u015fturma<\/h4>\n<p>E\u011fer hen\u00fcz bir Angular projeniz yoksa, Angular CLI kullanarak yeni bir proje olu\u015fturabilirsiniz:<\/p>\n<pre><code class=\"language-bash\">ng new ngrx-counter-app --routing false --style css\ncd ngrx-counter-app<\/code><\/pre>\n<h4>ngrx Kurulumu<\/h4>\n<p>ngrx paketlerini projenize eklemek i\u00e7in <code>@ngrx\/schematics<\/code> kullanabilirsiniz. Bu, gerekli ba\u011f\u0131ml\u0131l\u0131klar\u0131 y\u00fckleyecek ve <code>StoreModule<\/code>&#8216;\u00fc uygulaman\u0131z\u0131n k\u00f6k mod\u00fcl\u00fcne (<code>app.module.ts<\/code>) otomatik olarak yap\u0131land\u0131racakt\u0131r.<\/p>\n<pre><code class=\"language-bash\">ng add @ngrx\/store<\/code><\/pre>\n<p>Bu komut, <code>@ngrx\/store<\/code> paketini kuracak ve <code>app.module.ts<\/code> dosyan\u0131z\u0131 a\u015fa\u011f\u0131daki gibi g\u00fcncelleyecektir:<\/p>\n<pre><code class=\"language-typescript\">\/\/ src\/app\/app.module.ts\nimport { NgModule, isDevMode } from '@angular\/core';\nimport { BrowserModule } from '@angular\/platform-browser';\nimport { StoreModule } from '@ngrx\/store'; \/\/ ngrx\/store eklendi\nimport { StoreDevtoolsModule } from '@ngrx\/store-devtools'; \/\/ ngrx\/store-devtools eklendi\nimport { AppComponent } from '.\/app.component';\n\n@NgModule({\n  declarations: [\n    AppComponent\n  ],\n  imports: [\n    BrowserModule,\n    StoreModule.forRoot({}), \/\/ K\u00f6k durum nesnesi tan\u0131mland\u0131\n    StoreDevtoolsModule.instrument({ maxAge: 25, logOnly: !isDevMode() }) \/\/ Geli\u015ftirici ara\u00e7lar\u0131\n  ],\n  providers: [],\n  bootstrap: [AppComponent]\n})\nexport class AppModule { }<\/code><\/pre>\n<p><code>StoreModule.forRoot({})<\/code> ifadesi, uygulaman\u0131z\u0131n k\u00f6k durumunu tan\u0131mlar. \u015eimdilik bo\u015f bir nesne olarak b\u0131rakabiliriz. <code>StoreDevtoolsModule<\/code> ise Redux DevTools eklentisi ile entegrasyonu sa\u011flar, bu da durum de\u011fi\u015fikliklerini izlemek ve hata ay\u0131klamak i\u00e7in \u00e7ok kullan\u0131\u015fl\u0131d\u0131r.<\/p>\n<h3>Ad\u0131m Ad\u0131m ngrx Uygulamas\u0131 Olu\u015fturma: Basit Bir Saya\u00e7<\/h3>\n<p>\u015eimdi, ngrx&#8217;in temel bile\u015fenlerini kullanarak basit bir saya\u00e7 uygulamas\u0131 geli\u015ftirelim. Bu saya\u00e7, art\u0131rma, azaltma ve s\u0131f\u0131rlama i\u015flevlerine sahip olacak.<\/p>\n<h4>1. State Tan\u0131mlama<\/h4>\n<p>\u00d6ncelikle, uygulaman\u0131z\u0131n durumunu (state) tan\u0131mlamam\u0131z gerekiyor. Basit bir saya\u00e7 i\u00e7in sadece bir <code>number<\/code> de\u011feri yeterli olacakt\u0131r. Genellikle durumunuzu bir aray\u00fcz (interface) ile tan\u0131mlamak iyi bir pratiktir.<\/p>\n<p><code>src\/app\/state\/app.state.ts<\/code> (veya <code>src\/app\/counter\/counter.state.ts<\/code> gibi daha mod\u00fcler bir yap\u0131)<\/p>\n<pre><code class=\"language-typescript\">export interface AppState {\n  counter: number;\n}\n\nexport const initialState: AppState = {\n  counter: 0\n};<\/code><\/pre>\n<p>Burada <code>AppState<\/code> aray\u00fcz\u00fc, uygulamam\u0131z\u0131n k\u00f6k durumunun nas\u0131l g\u00f6r\u00fcnece\u011fini belirtir. <code>initialState<\/code> ise uygulaman\u0131n ba\u015flang\u0131\u00e7 durumunu tan\u0131mlar.<\/p>\n<h4>2. Actions Tan\u0131mlama<\/h4>\n<p>Action&#8217;lar, uygulamam\u0131zdaki olaylar\u0131 temsil eder. Saya\u00e7 uygulamam\u0131z i\u00e7in &#8220;art\u0131r&#8221;, &#8220;azalt&#8221; ve &#8220;s\u0131f\u0131rla&#8221; olmak \u00fczere \u00fc\u00e7 action&#8217;a ihtiyac\u0131m\u0131z var. ngrx&#8217;in <code>@ngrx\/store<\/code> paketinden <code>createAction<\/code> ve <code>props<\/code> fonksiyonlar\u0131n\u0131 kullanarak action&#8217;lar\u0131 tan\u0131mlayabiliriz.<\/p>\n<p><code>src\/app\/state\/counter.actions.ts<\/code><\/p>\n<pre><code class=\"language-typescript\">import { createAction, props } from '@ngrx\/store';\n\n\/\/ [Counter] \u00d6n eki, bu action'\u0131n hangi alana ait oldu\u011funu g\u00f6sterir.\n\/\/ Bu bir isimlendirme kural\u0131d\u0131r ve okunabilirli\u011fi art\u0131r\u0131r.\n\nexport const increment = createAction('[Counter] Increment');\nexport const decrement = createAction('[Counter] Decrement');\nexport const reset = createAction(\n  '[Counter] Reset',\n  props<{ value: number }>() \/\/ Bu action bir payload (y\u00fck) ta\u015f\u0131yacak\n);\n\n\/\/ Effects i\u00e7in de action'lar tan\u0131mlayabiliriz (ileride kullanaca\u011f\u0131z)\nexport const loadCounter = createAction('[Counter] Load Counter');\nexport const loadCounterSuccess = createAction(\n  '[Counter] Load Counter Success',\n  props<{ data: number }>()\n);\nexport const loadCounterFailure = createAction(\n  '[Counter] Load Counter Failure',\n  props<{ error: any }>()\n);<\/code><\/pre>\n<p><code>createAction<\/code> fonksiyonu, benzersiz bir t\u00fcr dizesi al\u0131r. <code>props<\/code> fonksiyonu ise action ile birlikte ta\u015f\u0131nacak ek verileri (payload) tan\u0131mlamam\u0131z\u0131 sa\u011flar. <code>reset<\/code> action&#8217;\u0131 bir <code>value<\/code> payload&#8217;\u0131 alarak sayac\u0131 belirli bir de\u011fere s\u0131f\u0131rlayacakt\u0131r.<\/p>\n<h4>3. Reducers Olu\u015fturma<\/h4>\n<p>Reducers, action&#8217;lar\u0131 dinleyen ve duruma yeni bir de\u011fer atayan saf fonksiyonlard\u0131r. <code>@ngrx\/store<\/code> paketinden <code>createReducer<\/code> ve <code>on<\/code> fonksiyonlar\u0131n\u0131 kullanarak reducer&#8217;\u0131m\u0131z\u0131 olu\u015fturabiliriz.<\/p>\n<p><code>src\/app\/state\/counter.reducer.ts<\/code><\/p>\n<pre><code class=\"language-typescript\">import { createReducer, on } from '@ngrx\/store';\nimport { increment, decrement, reset, loadCounterSuccess } from '.\/counter.actions';\nimport { initialState } from '.\/app.state'; \/\/ Ba\u015flang\u0131\u00e7 durumunu import ediyoruz\n\nexport const counterReducer = createReducer(\n  initialState, \/\/ Reducer'\u0131n ba\u015flang\u0131\u00e7 durumu\n  on(increment, (state) => ({ ...state, counter: state.counter + 1 })), \/\/ Art\u0131rma action'\u0131\n  on(decrement, (state) => ({ ...state, counter: state.counter - 1 })), \/\/ Azaltma action'\u0131\n  on(reset, (state, { value }) => ({ ...state, counter: value })), \/\/ S\u0131f\u0131rlama action'\u0131 (payload ile)\n  on(loadCounterSuccess, (state, { data }) => ({ ...state, counter: data })) \/\/ Async y\u00fckleme ba\u015far\u0131l\u0131\n);<\/code><\/pre>\n<p>*   <code>createReducer<\/code> fonksiyonu, ba\u015flang\u0131\u00e7 durumunu ve bir dizi <code>on<\/code> fonksiyonunu al\u0131r.<br \/>\n*   <code>on<\/code> fonksiyonu, belirli bir action tetiklendi\u011finde \u00e7al\u0131\u015facak bir geri \u00e7a\u011f\u0131rma (callback) fonksiyonu tan\u0131mlar.<br \/>\n*   Bu geri \u00e7a\u011f\u0131rma fonksiyonu, mevcut durumu (<code>state<\/code>) ve action&#8217;\u0131n kendisini (e\u011fer payload varsa) al\u0131r.<br \/>\n*   <strong>\u00d6nemli:<\/strong> Reducer fonksiyonlar\u0131, mevcut durumu do\u011frudan de\u011fi\u015ftirmemeli (immutable olmal\u0131). Bunun yerine, mevcut durumun bir kopyas\u0131n\u0131 almal\u0131 ve sadece de\u011fi\u015fen \u00f6zellikleri g\u00fcncellemelidir. Spread operat\u00f6r\u00fc (<code>...state<\/code>) bu ama\u00e7la kullan\u0131l\u0131r.<\/p>\n<h4>4. Store&#8217;u Uygulamaya Entegre Etme<\/h4>\n<p>\u015eimdi reducer&#8217;\u0131m\u0131z\u0131 <code>app.module.ts<\/code> dosyas\u0131ndaki <code>StoreModule.forRoot()<\/code> metoduna eklememiz gerekiyor.<\/p>\n<pre><code class=\"language-typescript\">\/\/ src\/app\/app.module.ts\nimport { NgModule, isDevMode } from '@angular\/core';\nimport { BrowserModule } from '@angular\/platform-browser';\nimport { StoreModule } from '@ngrx\/store';\nimport { StoreDevtoolsModule } from '@ngrx\/store-devtools';\nimport { AppComponent } from '.\/app.component';\nimport { counterReducer } from '.\/state\/counter.reducer'; \/\/ Reducer'\u0131m\u0131z\u0131 import ediyoruz\nimport { AppState } from '.\/state\/app.state'; \/\/ AppState aray\u00fcz\u00fcn\u00fc import ediyoruz\n\n@NgModule({\n  declarations: [\n    AppComponent\n  ],\n  imports: [\n    BrowserModule,\n    StoreModule.forRoot<AppState>({ \/\/ AppState tipini belirtiyoruz\n      counter: counterReducer \/\/ 'counter' anahtar\u0131 alt\u0131nda counterReducer'\u0131 kaydediyoruz\n    }),\n    StoreDevtoolsModule.instrument({ maxAge: 25, logOnly: !isDevMode() })\n  ],\n  providers: [],\n  bootstrap: [AppComponent]\n})\nexport class AppModule { }<\/code><\/pre>\n<p>Burada <code>StoreModule.forRoot<AppState>({ counter: counterReducer })<\/code> ile global durumumuzun <code>counter<\/code> adl\u0131 bir \u00f6zelli\u011fe sahip oldu\u011funu ve bu \u00f6zelli\u011fin <code>counterReducer<\/code> taraf\u0131ndan y\u00f6netildi\u011fini belirtiyoruz. Art\u0131k <code>Store<\/code> servisimiz, <code>AppState<\/code> aray\u00fcz\u00fcne uygun bir yap\u0131ya sahip olacak.<\/p>\n<h4>5. Store&#8217;u Kullanma (Component Taraf\u0131)<\/h4>\n<p>Art\u0131k bile\u015fenlerimizden durumu okuyabilir ve action&#8217;lar g\u00f6nderebiliriz. <code>AppComponent<\/code>&#8216;i g\u00fcncelleyelim.<\/p>\n<p><code>src\/app\/app.component.ts<\/code><\/p>\n<pre><code class=\"language-typescript\">import { Component } from '@angular\/core';\nimport { Store } from '@ngrx\/store';\nimport { Observable } from 'rxjs';\nimport { increment, decrement, reset, loadCounter } from '.\/state\/counter.actions';\nimport { AppState } from '.\/state\/app.state';\n\n@Component({\n  selector: 'app-root',\n  template: <code>\n    <div>\n      \n      <button (click)=\"increment()\">Art\u0131r<\/button>\n      <button (click)=\"decrement()\">Azalt<\/button>\n      <button (click)=\"reset(0)\">S\u0131f\u0131rla (0)<\/button>\n      <button (click)=\"reset(10)\">S\u0131f\u0131rla (10)<\/button>\n      <button (click)=\"loadCounter()\">Sayac\u0131 Y\u00fckle (Async)<\/button>\n    <\/div>\n  <\/code>\n})\nexport class AppComponent {\n  counter$: Observable<number>;\n\n  constructor(private store: Store<AppState>) {\n    \/\/ Store'dan 'counter' durumunu se\u00e7iyoruz.\n    \/\/ 'select' metodu bir Observable d\u00f6nd\u00fcr\u00fcr.\n    this.counter$ = this.store.select(state => state.counter);\n  }\n\n  increment() {\n    this.store.dispatch(increment()); \/\/ increment action'\u0131n\u0131 g\u00f6nder\n  }\n\n  decrement() {\n    this.store.dispatch(decrement()); \/\/ decrement action'\u0131n\u0131 g\u00f6nder\n  }\n\n  reset(value: number) {\n    this.store.dispatch(reset({ value })); \/\/ reset action'\u0131n\u0131 payload ile g\u00f6nder\n  }\n\n  loadCounter() {\n    this.store.dispatch(loadCounter()); \/\/ loadCounter action'\u0131n\u0131 g\u00f6nder (Effects taraf\u0131ndan i\u015flenecek)\n  }\n}<\/code><\/pre>\n<p>*   <code>Store<AppState><\/code> servisini enjekte ediyoruz.<br \/>\n*   <code>this.store.select(state => state.counter)<\/code> ile <code>AppState<\/code> i\u00e7indeki <code>counter<\/code> \u00f6zelli\u011fini se\u00e7iyoruz. Bu bir RxJS <code>Observable<\/code> d\u00f6nd\u00fcr\u00fcr, bu y\u00fczden \u015fablonumuzda <code>async<\/code> pipe ile abone oluyoruz.<br \/>\n*   <code>this.store.dispatch(action())<\/code> ile action&#8217;lar\u0131 Store&#8217;a g\u00f6nderiyoruz. Store, bu action&#8217;lar\u0131 dinleyen reducer&#8217;lar\u0131 tetikler.<\/p>\n<h4>6. Selectors Olu\u015fturma<\/h4>\n<p>Selector&#8217;lar, durumdan belirli veri par\u00e7alar\u0131n\u0131 se\u00e7mek ve t\u00fcretilmi\u015f durumlar olu\u015fturmak i\u00e7in kullan\u0131l\u0131r. <code>createSelector<\/code> fonksiyonu ile memoized (belle\u011fe al\u0131nm\u0131\u015f) selector&#8217;lar olu\u015fturabiliriz, bu da performans a\u00e7\u0131s\u0131ndan \u00f6nemlidir \u00e7\u00fcnk\u00fc ayn\u0131 girdi i\u00e7in hesaplama tekrarlanmaz.<\/p>\n<p><code>src\/app\/state\/counter.selectors.ts<\/code><\/p>\n<pre><code class=\"language-typescript\">import { createSelector, createFeatureSelector } from '@ngrx\/store';\nimport { AppState } from '.\/app.state';\n\n\/\/ K\u00f6k durumdan 'counter' \u00f6zelli\u011fini se\u00e7en bir feature selector tan\u0131ml\u0131yoruz.\n\/\/ Bu, genellikle daha b\u00fcy\u00fck uygulamalarda mod\u00fcl bazl\u0131 durumlar\u0131 se\u00e7mek i\u00e7in kullan\u0131l\u0131r.\nexport const selectCounterState = createFeatureSelector<AppState>('counter');\n\n\/\/ selectCounterState'i girdi olarak kullanan bir selector.\n\/\/ Bu selector, 'counter' \u00f6zelli\u011finin kendisini d\u00f6nd\u00fcr\u00fcr.\nexport const selectCounter = createSelector(\n  selectCounterState,\n  (state: AppState) => state.counter\n);\n\n\/\/ T\u00fcretilmi\u015f bir durum \u00f6rne\u011fi: sayac\u0131n \u00e7ift mi tek mi oldu\u011funu kontrol eden selector\nexport const selectIsEven = createSelector(\n  selectCounter,\n  (counter: number) => counter % 2 === 0\n);<\/code><\/pre>\n<p>\u015eimdi <code>AppComponent<\/code>&#8216;te bu selector&#8217;lar\u0131 kullanabiliriz:<\/p>\n<pre><code class=\"language-typescript\">\/\/ src\/app\/app.component.ts'te de\u011fi\u015fiklikler\nimport { Component } from '@angular\/core';\nimport { Store } from '@ngrx\/store';\nimport { Observable } from 'rxjs';\nimport { increment, decrement, reset, loadCounter } from '.\/state\/counter.actions';\nimport { AppState } from '.\/state\/app.state';\nimport { selectCounter, selectIsEven } from '.\/state\/counter.selectors'; \/\/ Selector'lar\u0131 import et\n\n@Component({\n  selector: 'app-root',\n  template: <code>\n    <div>\n      \n      <h2>Say\u0131 {{ (isEven$ | async) ? '\u00e7ift' : 'tek' }}<\/h2>\n      <button (click)=\"increment()\">Art\u0131r<\/button>\n      <button (click)=\"decrement()\">Azalt<\/button>\n      <button (click)=\"reset(0)\">S\u0131f\u0131rla (0)<\/button>\n      <button (click)=\"reset(10)\">S\u0131f\u0131rla (10)<\/button>\n      <button (click)=\"loadCounter()\">Sayac\u0131 Y\u00fckle (Async)<\/button>\n    <\/div>\n  <\/code>\n})\nexport class AppComponent {\n  counter$: Observable<number>;\n  isEven$: Observable<boolean>; \/\/ Yeni Observable\n\n  constructor(private store: Store<AppState>) {\n    this.counter$ = this.store.select(selectCounter); \/\/ Selector kullanarak se\u00e7iyoruz\n    this.isEven$ = this.store.select(selectIsEven);   \/\/ T\u00fcretilmi\u015f selector kullan\u0131yoruz\n  }\n\n  \/\/ ... (di\u011fer metodlar ayn\u0131 kal\u0131r)\n}<\/code><\/pre>\n<p>Selector&#8217;lar, bile\u015fenlerin do\u011frudan durumun yap\u0131s\u0131n\u0131 bilmesini engeller, bu da kodun daha mod\u00fcler ve bak\u0131m\u0131 kolay olmas\u0131n\u0131 sa\u011flar. Ayr\u0131ca, <code>createSelector<\/code>&#8216;\u0131n memoization \u00f6zelli\u011fi sayesinde, durum de\u011fi\u015fmedi\u011fi s\u00fcrece ayn\u0131 selector&#8217;\u0131n \u00e7\u0131kt\u0131s\u0131 yeniden hesaplanmaz, bu da performans\u0131 art\u0131r\u0131r.<\/p>\n<h3>ngrx\/effects ile Asenkron \u0130\u015flemler ve Yan Etkiler<\/h3>\n<p>Reducer&#8217;lar saf fonksiyonlar olmal\u0131 ve yan etkilere neden olmamal\u0131d\u0131r. Peki ya API \u00e7a\u011fr\u0131lar\u0131, router navigasyonlar\u0131 veya veritaban\u0131 i\u015flemleri gibi asenkron i\u015flemler? \u0130\u015fte bu noktada <code>ngrx\/effects<\/code> devreye girer. Effects, action&#8217;lar\u0131 dinler, yan etkileri ger\u00e7ekle\u015ftirir ve genellikle yeni action&#8217;lar g\u00f6ndererek Store&#8217;u g\u00fcnceller.<\/p>\n<h4>Effects Kurulumu<\/h4>\n<p><code>ngrx\/effects<\/code> paketini projenize ekleyin:<\/p>\n<pre><code class=\"language-bash\">ng add @ngrx\/effects<\/code><\/pre>\n<p>Bu komut <code>EffectsModule<\/code>&#8216;\u00fc <code>app.module.ts<\/code>&#8216;e ekleyecektir.<\/p>\n<pre><code class=\"language-typescript\">\/\/ src\/app\/app.module.ts'te olu\u015fan de\u011fi\u015fiklik\nimport { EffectsModule } from '@ngrx\/effects';\n\n@NgModule({\n  \/\/ ...\n  imports: [\n    \/\/ ...\n    EffectsModule.forRoot([]), \/\/ Bo\u015f bir dizi ile ba\u015flar\u0131z\n    \/\/ ...\n  ],\n  \/\/ ...\n})\nexport class AppModule { }<\/code><\/pre>\n<h4>Effects Olu\u015fturma<\/h4>\n<p><code>src\/app\/state\/counter.effects.ts<\/code><\/p>\n<pre><code class=\"language-typescript\">import { Injectable } from '@angular\/core';\nimport { Actions, createEffect, ofType } from '@ngrx\/effects';\nimport { of } from 'rxjs';\nimport { map, concatMap, catchError, delay } from 'rxjs\/operators';\nimport { loadCounter, loadCounterSuccess, loadCounterFailure } from '.\/counter.actions';\n\n@Injectable()\nexport class CounterEffects {\n  constructor(private actions$: Actions) {}\n\n  loadCounter$ = createEffect(() =>\n    this.actions$.pipe(\n      ofType(loadCounter), \/\/ Sadece 'loadCounter' action'\u0131n\u0131 dinle\n      concatMap(() =>\n        \/\/ Ger\u00e7ek bir API \u00e7a\u011fr\u0131s\u0131 yerine bir sim\u00fclasyon yap\u0131yoruz\n        of(Math.floor(Math.random() * 100)).pipe( \/\/ Rastgele bir say\u0131 \u00fcret\n          delay(1000), \/\/ 1 saniye gecikme sim\u00fclasyonu\n          map(data => loadCounterSuccess({ data })), \/\/ Ba\u015far\u0131l\u0131 olursa loadCounterSuccess action'\u0131n\u0131 g\u00f6nder\n          catchError(error => of(loadCounterFailure({ error }))) \/\/ Hata olursa loadCounterFailure action'\u0131n\u0131 g\u00f6nder\n        )\n      )\n    )\n  );\n}<\/code><\/pre>\n<p>*   <code>@Injectable()<\/code> dekorat\u00f6r\u00fc, bu s\u0131n\u0131f\u0131n ba\u011f\u0131ml\u0131l\u0131k enjeksiyonu i\u00e7in kullan\u0131labilir oldu\u011funu belirtir.<br \/>\n*   <code>Actions<\/code> servisi, uygulaman\u0131n t\u00fcm action&#8217;lar\u0131n\u0131n bir <code>Observable<\/code> ak\u0131\u015f\u0131d\u0131r.<br \/>\n*   <code>createEffect<\/code> fonksiyonu, bir yan etkiyi tan\u0131mlar.<br \/>\n*   <code>this.actions$.pipe()<\/code>: <code>Actions<\/code> ak\u0131\u015f\u0131 \u00fczerinde RxJS operat\u00f6rlerini kullan\u0131r\u0131z.<br \/>\n*   <code>ofType(loadCounter)<\/code>: Sadece <code>loadCounter<\/code> action&#8217;\u0131 tetiklendi\u011finde sonraki operat\u00f6rleri \u00e7al\u0131\u015ft\u0131rmam\u0131z\u0131 sa\u011flar.<br \/>\n*   <code>concatMap()<\/code>: \u00d6nceki Observable tamamland\u0131\u011f\u0131nda yeni bir Observable&#8217;\u0131 birle\u015ftirmek i\u00e7in kullan\u0131l\u0131r. Bu, s\u0131ral\u0131 asenkron i\u015flemleri y\u00f6netmek i\u00e7in iyidir.<br \/>\n<em>   <code>of(Math.floor(Math.random() <\/em> 100)).pipe(delay(1000))<\/code>: Bir API \u00e7a\u011fr\u0131s\u0131n\u0131 taklit eden bir RxJS Observable&#8217;\u0131 olu\u015fturur. 1 saniye sonra rastgele bir say\u0131 yayar.<br \/>\n*   <code>map(data => loadCounterSuccess({ data }))<\/code>: Sim\u00fclasyon ba\u015far\u0131l\u0131 oldu\u011funda, <code>loadCounterSuccess<\/code> action&#8217;\u0131n\u0131 uygun payload ile dispatch ederiz.<br \/>\n*   <code>catchError(error => of(loadCounterFailure({ error })))<\/code>: E\u011fer bir hata olu\u015fursa, <code>loadCounterFailure<\/code> action&#8217;\u0131n\u0131 dispatch ederiz.<\/p>\n<h4>Effects Mod\u00fcl\u00fcn\u00fc Yap\u0131land\u0131rma<\/h4>\n<p>Olu\u015fturdu\u011fumuz <code>CounterEffects<\/code> s\u0131n\u0131f\u0131n\u0131 <code>app.module.ts<\/code> dosyas\u0131ndaki <code>EffectsModule.forRoot()<\/code> metoduna eklememiz gerekiyor.<\/p>\n<pre><code class=\"language-typescript\">\/\/ src\/app\/app.module.ts'te de\u011fi\u015fiklikler\nimport { EffectsModule } from '@ngrx\/effects';\nimport { CounterEffects } from '.\/state\/counter.effects'; \/\/ Effects s\u0131n\u0131f\u0131m\u0131z\u0131 import ediyoruz\n\n@NgModule({\n  \/\/ ...\n  imports: [\n    \/\/ ...\n    EffectsModule.forRoot([CounterEffects]), \/\/ CounterEffects'i kaydediyoruz\n    \/\/ ...\n  ],\n  \/\/ ...\n})\nexport class AppModule { }<\/code><\/pre>\n<p>Art\u0131k <code>AppComponent<\/code>&#8216;teki <code>loadCounter()<\/code> metodu tetiklendi\u011finde, <code>CounterEffects<\/code>&#8216;teki <code>loadCounter$<\/code> effect&#8217;i \u00e7al\u0131\u015facak, asenkron i\u015flemi sim\u00fcle edecek ve sonucuna g\u00f6re <code>loadCounterSuccess<\/code> veya <code>loadCounterFailure<\/code> action&#8217;\u0131n\u0131 Store&#8217;a g\u00f6nderecektir. <code>counterReducer<\/code> ise <code>loadCounterSuccess<\/code> action&#8217;\u0131n\u0131 dinleyerek sayac\u0131 g\u00fcncelleyecektir.<\/p>\n<h3>ngrx\/entity ile Koleksiyon Y\u00f6netimi<\/h3>\n<p>\u00c7o\u011fu uygulamada, kullan\u0131c\u0131lar, \u00fcr\u00fcnler, g\u00f6revler gibi bir dizi \u00f6\u011feyi y\u00f6netmek gerekir. Bu t\u00fcr koleksiyonlar\u0131 y\u00f6netmek, ekleme, g\u00fcncelleme, silme ve s\u0131ralama gibi i\u015flemleri i\u00e7erir. <code>ngrx\/entity<\/code> mod\u00fcl\u00fc, bu t\u00fcr koleksiyonlar\u0131 y\u00f6netmek i\u00e7in optimize edilmi\u015f reducer&#8217;lar ve selector&#8217;lar olu\u015fturarak boilerplate kodunu azalt\u0131r ve performans\u0131 art\u0131r\u0131r.<\/p>\n<p><code>ngrx\/entity<\/code> kullanmak, koleksiyonlar\u0131 normalle\u015ftirilmi\u015f bir yap\u0131da (ID&#8217;ye g\u00f6re bir nesne ve t\u00fcm ID&#8217;lerin bir dizisi) tutman\u0131z\u0131 sa\u011flar, bu da de\u011fi\u015fiklikleri daha verimli hale getirir.<\/p>\n<p>\u00d6rne\u011fin, bir &#8220;Todo&#8221; listesi y\u00f6netmek i\u00e7in:<\/p>\n<p>1.  <strong>Entity Adapter Olu\u015fturma:<\/strong><\/p>\n<pre><code class=\"language-typescript\">import { createEntityAdapter, EntityAdapter, EntityState } from '@ngrx\/entity';\n\n    export interface Todo {\n      id: string;\n      title: string;\n      completed: boolean;\n    }\n\n    export interface TodoState extends EntityState<Todo> {\n      \/\/ Ek durum \u00f6zellikleri buraya eklenebilir\n      selectedTodoId: string | null;\n    }\n\n    export const todoAdapter: EntityAdapter<Todo> = createEntityAdapter<Todo>();\n\n    export const initialTodoState: TodoState = todoAdapter.getInitialState({\n      selectedTodoId: null\n    });<\/code><\/pre>\n<p>2.  <strong>Reducer&#8217;da Kullanma:<\/strong><\/p>\n<pre><code class=\"language-typescript\">import { createReducer, on } from '@ngrx\/store';\n    import { todoAdapter, initialTodoState } from '.\/todo.state';\n    import * as TodoActions from '.\/todo.actions';\n\n    export const todoReducer = createReducer(\n      initialTodoState,\n      on(TodoActions.addTodo, (state, { todo }) => {\n        return todoAdapter.addOne(todo, state);\n      }),\n      on(TodoActions.updateTodo, (state, { update }) => {\n        return todoAdapter.updateOne(update, state);\n      }),\n      on(TodoActions.deleteTodo, (state, { id }) => {\n        return todoAdapter.removeOne(id, state);\n      }),\n      on(TodoActions.loadTodosSuccess, (state, { todos }) => {\n        return todoAdapter.setAll(todos, state);\n      })\n      \/\/ ... di\u011fer action'lar\n    );<\/code><\/pre>\n<p>3.  <strong>Selector&#8217;larda Kullanma:<\/strong><\/p>\n<pre><code class=\"language-typescript\">import { createFeatureSelector, createSelector } from '@ngrx\/store';\n    import { TodoState, todoAdapter } from '.\/todo.state';\n\n    export const selectTodoState = createFeatureSelector<TodoState>('todos');\n\n    export const {\n      selectIds,\n      selectEntities,\n      selectAll,\n      selectTotal,\n    } = todoAdapter.getSelectors(selectTodoState);\n\n    export const selectSelectedTodoId = createSelector(\n      selectTodoState,\n      (state: TodoState) => state.selectedTodoId\n    );\n\n    export const selectSelectedTodo = createSelector(\n      selectEntities,\n      selectSelectedTodoId,\n      (entities, selectedId) => selectedId && entities[selectedId]\n    );<\/code><\/pre>\n<p><code>ngrx\/entity<\/code>, \u00f6zellikle b\u00fcy\u00fck ve s\u0131k g\u00fcncellenen koleksiyonlar i\u00e7in kodunuzu \u00f6nemli \u00f6l\u00e7\u00fcde basitle\u015ftirir ve performans\u0131 art\u0131r\u0131r.<\/p>\n<h3>ngrx Geli\u015ftirici Ara\u00e7lar\u0131 (DevTools)<\/h3>\n<p>ngrx&#8217;in en b\u00fcy\u00fck avantajlar\u0131ndan biri, Redux DevTools ile olan entegrasyonudur. <code>StoreDevtoolsModule<\/code> sayesinde, taray\u0131c\u0131n\u0131zdaki Redux DevTools eklentisini kullanarak uygulaman\u0131z\u0131n durumunu ve t\u00fcm action ge\u00e7mi\u015fini izleyebilirsiniz. Bu, hata ay\u0131klama s\u00fcrecini inan\u0131lmaz derecede kolayla\u015ft\u0131r\u0131r.<\/p>\n<p><code>app.module.ts<\/code> dosyas\u0131nda <code>StoreDevtoolsModule.instrument()<\/code> ile zaten kurmu\u015ftuk. Geli\u015ftirme ortam\u0131n\u0131zda bu ara\u00e7lar\u0131 kullanarak:<\/p>\n<p>*   <strong>Durum Ge\u00e7mi\u015fini G\u00f6r\u00fcnt\u00fcleme:<\/strong> Uygulaman\u0131n durumunun her bir action&#8217;dan sonra nas\u0131l de\u011fi\u015fti\u011fini ad\u0131m ad\u0131m g\u00f6rebilirsiniz.<br \/>\n*   <strong>Time-Travel Debugging:<\/strong> Ge\u00e7mi\u015fteki bir duruma geri d\u00f6n\u00fcp uygulaman\u0131n o anki halini inceleyebilirsiniz.<br \/>\n*   <strong>Action&#8217;lar\u0131 \u0130nceleme:<\/strong> Hangi action&#8217;lar\u0131n ne zaman ve hangi payload ile g\u00f6nderildi\u011fini g\u00f6rebilirsiniz.<br \/>\n*   <strong>Durumu D\u00fczenleme:<\/strong> Anl\u0131k olarak durumu de\u011fi\u015ftirerek farkl\u0131 senaryolar\u0131 test edebilirsiniz.<\/p>\n<p>Bu ara\u00e7lar, ngrx ile \u00e7al\u0131\u015f\u0131rken geli\u015ftirici deneyimini b\u00fcy\u00fck \u00f6l\u00e7\u00fcde iyile\u015ftirir ve karma\u015f\u0131k durum sorunlar\u0131n\u0131 h\u0131zla te\u015fhis etmenize yard\u0131mc\u0131 olur.<\/p>\n<h3>ngrx&#8217;in Avantajlar\u0131 ve Dezavantajlar\u0131<\/h3>\n<p>Her teknoloji gibi, ngrx&#8217;in de kendine g\u00f6re avantajlar\u0131 ve dezavantajlar\u0131 vard\u0131r.<\/p>\n<h4>Avantajlar\u0131:<\/h4>\n<p>*   <strong>Merkezi Durum Y\u00f6netimi:<\/strong> Uygulaman\u0131n t\u00fcm durumu tek bir yerde tutulur, bu da veri ak\u0131\u015f\u0131n\u0131 \u00f6ng\u00f6r\u00fclebilir hale getirir.<br \/>\n*   <strong>Tahmin Edilebilir Durum:<\/strong> Durum de\u011fi\u015fiklikleri action&#8217;lar ve saf reducer&#8217;lar arac\u0131l\u0131\u011f\u0131yla ger\u00e7ekle\u015fti\u011fi i\u00e7in, durumun ne zaman ve nas\u0131l de\u011fi\u015fti\u011fi her zaman bellidir.<br \/>\n*   <strong>Geli\u015ftirici Ara\u00e7lar\u0131:<\/strong> Redux DevTools ile m\u00fckemmel entegrasyon, hata ay\u0131klamay\u0131 ve durum ge\u00e7mi\u015fini izlemeyi kolayla\u015ft\u0131r\u0131r.<br \/>\n*   <strong>B\u00fcy\u00fck \u00d6l\u00e7ekli Uygulamalar \u0130\u00e7in Uygunluk:<\/strong> Karma\u015f\u0131k ve b\u00fcy\u00fck \u00f6l\u00e7ekli uygulamalarda durum karma\u015fas\u0131n\u0131 y\u00f6netmek i\u00e7in idealdir.<br \/>\n*   <strong>Performans Optimizasyonu:<\/strong> <code>createSelector<\/code> ile memoized selector&#8217;lar, gereksiz yeniden hesaplamalar\u0131 \u00f6nleyerek performans\u0131 art\u0131r\u0131r.<br \/>\n*   <strong>Test Edilebilirlik:<\/strong> Reducer&#8217;lar ve selector&#8217;lar saf fonksiyonlar oldu\u011fu i\u00e7in kolayca test edilebilirler. Effects&#8217;ler de izole bir \u015fekilde test edilebilir.<br \/>\n*   <strong>Mod\u00fclerlik:<\/strong> Uygulaman\u0131n farkl\u0131 katmanlar\u0131 (UI, i\u015f mant\u0131\u011f\u0131, yan etkiler) net bir \u015fekilde ayr\u0131lm\u0131\u015ft\u0131r.<\/p>\n<h4>Dezavantajlar\u0131:<\/h4>\n<p>*   <strong>\u00d6\u011frenme E\u011frisi:<\/strong> Redux prensiplerini ve RxJS operat\u00f6rlerini anlamak zaman alabilir. Yeni ba\u015flayanlar i\u00e7in ba\u015flang\u0131\u00e7ta g\u00f6z korkutucu olabilir.<br \/>\n*   <strong>Boilerplate Kodu:<\/strong> \u00d6zellikle k\u00fc\u00e7\u00fck uygulamalar i\u00e7in, \u00e7ok say\u0131da dosya (actions, reducers, effects, selectors) ve tekrar eden kod (boilerplate) olu\u015fturma ihtiyac\u0131 do\u011furabilir. Ancak ngrx schematics ve yeni API&#8217;ler (createAction, createReducer, createEffect) bu sorunu \u00f6nemli \u00f6l\u00e7\u00fcde azaltm\u0131\u015ft\u0131r.<br \/>\n*   <strong>K\u00fc\u00e7\u00fck Uygulamalar \u0130\u00e7in Gereksiz Karma\u015f\u0131kl\u0131k:<\/strong> E\u011fer uygulaman\u0131z\u0131n durumu basitse ve az say\u0131da bile\u015fen aras\u0131nda payla\u015f\u0131l\u0131yorsa, ngrx kullanmak gereksiz karma\u015f\u0131kl\u0131k getirebilir.<\/p>\n<h3>Ne Zaman ngrx Kullanmal\u0131?<\/h3>\n<p>ngrx her Angular uygulamas\u0131 i\u00e7in do\u011fru \u00e7\u00f6z\u00fcm de\u011fildir. A\u015fa\u011f\u0131daki senaryolarda ngrx kullanmay\u0131 d\u00fc\u015f\u00fcnebilirsiniz:<\/p>\n<p>*   <strong>Uygulaman\u0131z\u0131n Durumu Karma\u015f\u0131kla\u015ft\u0131\u011f\u0131nda:<\/strong> Bir\u00e7ok farkl\u0131 veri par\u00e7as\u0131n\u0131n birbiriyle ili\u015fkili oldu\u011fu ve bir\u00e7ok bile\u015fen taraf\u0131ndan kullan\u0131ld\u0131\u011f\u0131 durumlarda.<br \/>\n*   <strong>Bir\u00e7ok Bile\u015fenin Ayn\u0131 Duruma Eri\u015fmesi veya Durumu De\u011fi\u015ftirmesi Gerekti\u011finde:<\/strong> Bile\u015fen a\u011fac\u0131n\u0131n farkl\u0131 yerlerindeki bile\u015fenlerin ayn\u0131 veriler \u00fczerinde \u00e7al\u0131\u015fmas\u0131 gerekti\u011finde.<br \/>\n*   <strong>Asenkron \u0130\u015flemlerin Yo\u011fun Oldu\u011fu Durumlarda:<\/strong> API \u00e7a\u011fr\u0131lar\u0131, web soketleri veya di\u011fer asenkron veri ak\u0131\u015flar\u0131n\u0131n \u00e7ok oldu\u011fu uygulamalarda Effects mod\u00fcl\u00fc \u00e7ok faydal\u0131d\u0131r.<br \/>\n*   <strong>Durum De\u011fi\u015fikliklerinin \u0130zlenebilir ve Tahmin Edilebilir Olmas\u0131 Gerekti\u011finde:<\/strong> Uygulaman\u0131zda bir hata olu\u015ftu\u011funda, durumun hangi noktada ve hangi action ile de\u011fi\u015fti\u011fini kolayca tespit etmek istedi\u011finizde.<br \/>\n*   <strong>Ekip \u00dcyelerinin Redux Prensiplerine A\u015fina Oldu\u011fu Durumlarda:<\/strong> Ekibiniz zaten Redux veya benzeri bir desenle deneyimliyse, ngrx&#8217;e ge\u00e7i\u015f daha kolay olacakt\u0131r.<\/p>\n<p>Basit CRUD uygulamalar\u0131 veya az say\u0131da bile\u015feni olan k\u00fc\u00e7\u00fck uygulamalar i\u00e7in, servisler ve RxJS <code>Subject<\/code>&#8216;ler gibi daha hafif \u00e7\u00f6z\u00fcmler yeterli olabilir. ngrx&#8217;in getirdi\u011fi \u00f6\u011frenme maliyeti ve boilerplate kodunu g\u00f6z \u00f6n\u00fcnde bulundurarak, uygulaman\u0131z\u0131n ihtiya\u00e7lar\u0131na g\u00f6re bilin\u00e7li bir karar vermek \u00f6nemlidir.<\/p>\n<h3>Sonu\u00e7<\/h3>\n<p>ngrx, Angular uygulamalar\u0131nda Redux tarz\u0131 durum y\u00f6netimini uygulamak i\u00e7in g\u00fc\u00e7l\u00fc ve kapsaml\u0131 bir \u00e7\u00f6z\u00fcmd\u00fcr. Uygulaman\u0131z b\u00fcy\u00fcd\u00fck\u00e7e ortaya \u00e7\u0131kan durum y\u00f6netimi karma\u015f\u0131kl\u0131klar\u0131n\u0131 \u00e7\u00f6zmek, veri ak\u0131\u015f\u0131n\u0131 tahmin edilebilir k\u0131lmak ve hata ay\u0131klamay\u0131 kolayla\u015ft\u0131rmak i\u00e7in merkezi bir yakla\u015f\u0131m sunar. Store, Actions, Reducers, Selectors ve Effects gibi temel bile\u015fenleriyle, uygulaman\u0131z\u0131n durumunu, i\u015f mant\u0131\u011f\u0131n\u0131 ve yan etkilerini d\u00fczenli bir \u015fekilde ay\u0131rman\u0131za olanak tan\u0131r.<\/p>\n<p>Ba\u015flang\u0131\u00e7ta bir \u00f6\u011frenme e\u011frisi olsa da, ngrx&#8217;e yap\u0131lan yat\u0131r\u0131m, \u00f6zellikle b\u00fcy\u00fck ve karma\u015f\u0131k Angular projelerinde, daha s\u00fcrd\u00fcr\u00fclebilir, test edilebilir ve y\u00f6netilebilir bir kod taban\u0131 ile geri d\u00f6necektir. Geli\u015ftirici ara\u00e7lar\u0131 sayesinde, uygulaman\u0131z\u0131n durumunu izlemek ve hata ay\u0131klamak hi\u00e7 bu kadar kolay olmam\u0131\u015ft\u0131.<\/p>\n<p>Bu makalede sundu\u011fumuz basit saya\u00e7 \u00f6rne\u011fi, ngrx&#8217;in temel prensiplerini ve nas\u0131l \u00e7al\u0131\u015ft\u0131\u011f\u0131n\u0131 anlaman\u0131z i\u00e7in bir ba\u015flang\u0131\u00e7 noktas\u0131d\u0131r. ngrx ekosistemi olduk\u00e7a geni\u015ftir ve ke\u015ffedilmeyi bekleyen daha bir\u00e7ok g\u00fc\u00e7l\u00fc \u00f6zelli\u011fi (router-store, component-store, data, vb.) bulunmaktad\u0131r. Kendi projelerinizde ngrx&#8217;i deneyerek ve topluluk kaynaklar\u0131n\u0131 takip ederek bu g\u00fc\u00e7l\u00fc k\u00fct\u00fcphaneyi tam potansiyeliyle kullanabilirsiniz. Unutmay\u0131n, do\u011fru ara\u00e7lar\u0131 do\u011fru zamanda se\u00e7mek, ba\u015far\u0131l\u0131 bir yaz\u0131l\u0131m geli\u015ftirme s\u00fcrecinin anahtar\u0131d\u0131r.<\/body><\/p>\n","protected":false},"excerpt":{"rendered":"Angular&#8217;da Redux Tarz\u0131 Durum Y\u00f6netimi i\u00e7in ngrx ile Ba\u015flang\u0131\u00e7\nAngular, b\u00fcy\u00fck ve karma\u015f\u0131k kurumsal uygulamalar geli\u015ftirmek i\u00e7in g\u00fc\u00e7l\u00fc b","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"csco_page_header_type":"","csco_page_load_nextpost":"","csco_page_subscribe_form":"","csco_page_contact_form":"","footnotes":""},"categories":[1488],"tags":[],"class_list":{"0":"post-39438","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-angular","7":"cs-entry","8":"cs-video-wrap"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.5 (Yoast SEO v25.3.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Angular&#039;da Redux Tarz\u0131 Durum Y\u00f6netimi i\u00e7in ngrx ile Ba\u015flang\u0131\u00e7 - Kodlar\u0131n Gizemli D\u00fcnyas\u0131<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/fatihsoysal.com\/blog\/angularda-redux-tarzi-durum-yonetimi-icin-ngrx-ile-baslangic\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Angular&#039;da Redux Tarz\u0131 Durum Y\u00f6netimi i\u00e7in ngrx ile Ba\u015flang\u0131\u00e7\" \/>\n<meta property=\"og:description\" content=\"Angular&#039;da Redux Tarz\u0131 Durum Y\u00f6netimi i\u00e7in ngrx ile Ba\u015flang\u0131\u00e7 Angular, b\u00fcy\u00fck ve karma\u015f\u0131k kurumsal uygulamalar geli\u015ftirmek i\u00e7in g\u00fc\u00e7l\u00fc b\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/angularda-redux-tarzi-durum-yonetimi-icin-ngrx-ile-baslangic\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2026-02-21T10:40:51+00:00\" \/>\n<meta name=\"author\" content=\"Fatih Soysal\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Yazan:\" \/>\n\t<meta name=\"twitter:data1\" content=\"Fatih Soysal\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tahmini okuma s\u00fcresi\" \/>\n\t<meta name=\"twitter:data2\" content=\"20 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/angularda-redux-tarzi-durum-yonetimi-icin-ngrx-ile-baslangic\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/angularda-redux-tarzi-durum-yonetimi-icin-ngrx-ile-baslangic\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"Angular&#8217;da Redux Tarz\u0131 Durum Y\u00f6netimi i\u00e7in ngrx ile Ba\u015flang\u0131\u00e7\",\"datePublished\":\"2026-02-21T10:40:51+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/angularda-redux-tarzi-durum-yonetimi-icin-ngrx-ile-baslangic\/\"},\"wordCount\":2823,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"articleSection\":[\"Angular\"],\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/angularda-redux-tarzi-durum-yonetimi-icin-ngrx-ile-baslangic\/#respond\"]}],\"copyrightYear\":\"2026\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/angularda-redux-tarzi-durum-yonetimi-icin-ngrx-ile-baslangic\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/angularda-redux-tarzi-durum-yonetimi-icin-ngrx-ile-baslangic\/\",\"name\":\"Angular'da Redux Tarz\u0131 Durum Y\u00f6netimi i\u00e7in ngrx ile Ba\u015flang\u0131\u00e7 - Kodlar\u0131n Gizemli D\u00fcnyas\u0131\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2026-02-21T10:40:51+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/angularda-redux-tarzi-durum-yonetimi-icin-ngrx-ile-baslangic\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/angularda-redux-tarzi-durum-yonetimi-icin-ngrx-ile-baslangic\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/angularda-redux-tarzi-durum-yonetimi-icin-ngrx-ile-baslangic\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Angular&#8217;da Redux Tarz\u0131 Durum Y\u00f6netimi i\u00e7in ngrx ile Ba\u015flang\u0131\u00e7\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/\",\"name\":\"Fatihsoysal.com\",\"description\":\"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim\",\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"tr\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\",\"name\":\"Fatih Soysal\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"contentUrl\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"width\":512,\"height\":512,\"caption\":\"Fatih Soysal\"},\"logo\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\"},\"description\":\"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Angular'da Redux Tarz\u0131 Durum Y\u00f6netimi i\u00e7in ngrx ile Ba\u015flang\u0131\u00e7 - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/fatihsoysal.com\/blog\/angularda-redux-tarzi-durum-yonetimi-icin-ngrx-ile-baslangic\/","og_locale":"tr_TR","og_type":"article","og_title":"Angular'da Redux Tarz\u0131 Durum Y\u00f6netimi i\u00e7in ngrx ile Ba\u015flang\u0131\u00e7","og_description":"Angular'da Redux Tarz\u0131 Durum Y\u00f6netimi i\u00e7in ngrx ile Ba\u015flang\u0131\u00e7 Angular, b\u00fcy\u00fck ve karma\u015f\u0131k kurumsal uygulamalar geli\u015ftirmek i\u00e7in g\u00fc\u00e7l\u00fc b","og_url":"https:\/\/fatihsoysal.com\/blog\/angularda-redux-tarzi-durum-yonetimi-icin-ngrx-ile-baslangic\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2026-02-21T10:40:51+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"20 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/angularda-redux-tarzi-durum-yonetimi-icin-ngrx-ile-baslangic\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/angularda-redux-tarzi-durum-yonetimi-icin-ngrx-ile-baslangic\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"Angular&#8217;da Redux Tarz\u0131 Durum Y\u00f6netimi i\u00e7in ngrx ile Ba\u015flang\u0131\u00e7","datePublished":"2026-02-21T10:40:51+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/angularda-redux-tarzi-durum-yonetimi-icin-ngrx-ile-baslangic\/"},"wordCount":2823,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"articleSection":["Angular"],"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/angularda-redux-tarzi-durum-yonetimi-icin-ngrx-ile-baslangic\/#respond"]}],"copyrightYear":"2026","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/angularda-redux-tarzi-durum-yonetimi-icin-ngrx-ile-baslangic\/","url":"https:\/\/fatihsoysal.com\/blog\/angularda-redux-tarzi-durum-yonetimi-icin-ngrx-ile-baslangic\/","name":"Angular'da Redux Tarz\u0131 Durum Y\u00f6netimi i\u00e7in ngrx ile Ba\u015flang\u0131\u00e7 - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2026-02-21T10:40:51+00:00","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/angularda-redux-tarzi-durum-yonetimi-icin-ngrx-ile-baslangic\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/angularda-redux-tarzi-durum-yonetimi-icin-ngrx-ile-baslangic\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/angularda-redux-tarzi-durum-yonetimi-icin-ngrx-ile-baslangic\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Angular&#8217;da Redux Tarz\u0131 Durum Y\u00f6netimi i\u00e7in ngrx ile Ba\u015flang\u0131\u00e7"}]},{"@type":"WebSite","@id":"https:\/\/fatihsoysal.com\/blog\/#website","url":"https:\/\/fatihsoysal.com\/blog\/","name":"Fatihsoysal.com","description":"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim","publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"tr"},{"@type":["Person","Organization"],"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1","name":"Fatih Soysal","image":{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","contentUrl":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","width":512,"height":512,"caption":"Fatih Soysal"},"logo":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/"},"description":"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.","url":"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/"}]}},"yoast_meta":{"yoast_wpseo_title":"","yoast_wpseo_metadesc":"","yoast_wpseo_canonical":""},"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/39438","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/comments?post=39438"}],"version-history":[{"count":1,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/39438\/revisions"}],"predecessor-version":[{"id":39439,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/39438\/revisions\/39439"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=39438"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=39438"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=39438"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}