﻿
{"id":27530,"date":"2025-02-07T16:07:00","date_gmt":"2025-02-07T16:07:00","guid":{"rendered":"https:\/\/www.gencayyildiz.com\/blog\/?p=27530"},"modified":"2025-02-07T16:07:00","modified_gmt":"2025-02-07T16:07:00","slug":"angular-19-resource-api-ozelligini-inceleyelim","status":"publish","type":"post","link":"https:\/\/www.gencayyildiz.com\/blog\/angular-19-resource-api-ozelligini-inceleyelim\/","title":{"rendered":"Angular 19 &#8211; resource API \u00d6zelli\u011fini \u0130nceleyelim"},"content":{"rendered":"<div id=\"fb-root\"><\/div>\n<p>Merhaba,<\/p>\n<p>Bu i\u00e7eri\u011fimizde Angular 19 ile gelen, asenkron veri getirme ve durum y\u00f6netimi i\u015flemlerini daha basit ve efektif hale getiren <em>resource API<\/em> \u00f6zelli\u011fini inceleyece\u011fiz.<\/p>\n<h3>resource API Nedir?<\/h3>\n<p>Resource API&#8217;\u0131 anlamak i\u00e7in en do\u011frusu Angular 19&#8217;dan \u00f6nce bir durumu bar\u0131nd\u0131ran a\u015fa\u011f\u0131daki senaryoya kar\u015f\u0131n g\u00f6sterdi\u011fimiz tepkiyi ele almak ve oradaki davran\u0131\u015fa kar\u015f\u0131n resource API&#8217;\u0131n davran\u0131\u015f\u0131n\u0131 mukayesede bulunmakt\u0131r. \u015e\u00f6yle ki;<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nimport { Component, effect, inject, signal, WritableSignal } from '@angular\/core';\r\nimport { RouterOutlet } from '@angular\/router';\r\nimport { User } from '.\/models\/user';\r\nimport { UserService } from '.\/services\/user.service';\r\nimport { FormsModule } from '@angular\/forms'\r\n\r\n@Component({\r\n  selector: 'app-root',\r\n  imports: &#x5B;FormsModule],\r\n  template: `\r\n    &lt;h4&gt;User List&lt;\/h4&gt;\r\n    &lt;select (change)=&quot;userSelected($event)&quot;&gt;\r\n      @for (user of userList(); track user) {\r\n        &lt;option &#x5B;value]=&quot;user.id&quot;&gt;{{user.name}}&lt;\/option&gt;\r\n      }\r\n    &lt;\/select&gt;\r\n\r\n    &lt;hr&gt;\r\n    @if (userDetail()) {\r\n      &lt;label&gt;{{userDetail()?.name}}&lt;\/label&gt;\r\n      &lt;label&gt;{{userDetail()?.email}}&lt;\/label&gt;\r\n    }\r\n  `\r\n})\r\nexport class AppComponent {\r\n  userId: WritableSignal&lt;number&gt; = signal&lt;number&gt;(1);\r\n  userList: WritableSignal&lt;User&#x5B;]&gt; = signal&lt;User&#x5B;]&gt;(&#x5B;] as User&#x5B;]);\r\n  userDetail: WritableSignal&lt;User | undefined&gt; = signal&lt;User | undefined&gt;(undefined);\r\n\r\n  userService: UserService = inject(UserService);\r\n\r\n  async ngOnInit() {\r\n    const allUsers: User&#x5B;] = await this.userService.getUsers();\r\n    this.userList.set(allUsers);\r\n    const userDetail = await this.userService.getUserById(this.userId());\r\n    this.userDetail.set(userDetail);\r\n  }\r\n\r\n  userSelected(event: any) {\r\n    console.log(event.target.value);\r\n    this.userId.set(event.target.value);\r\n  }\r\n}\r\n<\/pre>\n<\/div>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2025\/02\/Angular-19-resource-API-Ozelligini-Inceleyelim.gif\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2025\/02\/Angular-19-resource-API-Ozelligini-Inceleyelim.gif\" alt=\"Angular 19 - resource API \u00d6zelli\u011fini \u0130nceleyelim\" width=\"300\" height=\"352\" class=\"alignleft size-full wp-image-27532\" \/><\/a>Yukar\u0131daki \u00e7al\u0131\u015fmay\u0131 ele al\u0131rsak e\u011fer kullan\u0131c\u0131 listesinden se\u00e7ilen kullan\u0131c\u0131n\u0131n detay bilgileri yap\u0131lan yeni bir istek neticesinde elde edilmekte ve a\u015fa\u011f\u0131da g\u00f6sterilmek istenmektedir. Tabi bunun i\u00e7in <em>userSelected<\/em> metodunda gerekli i\u015flemler yap\u0131lmakta ancak g\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere UI&#8217;da bu i\u015flemlere kar\u015f\u0131n bir de\u011fi\u015fim durumu s\u00f6z konusu olmamaktad\u0131r. Yani anlayaca\u011f\u0131n\u0131z, her ne kadar Angular&#8217;\u0131n son d\u00f6nemlerdeki g\u00f6zdesi olan <a href=\"https:\/\/www.gencayyildiz.com\/blog\/angular-16-signals-yapilanmasini-detayli-inceleyelim\/\" target=\"_blank\">signal<\/a>&#8216;lar\u0131 kullan\u0131yor olsak da bu durumda pek de i\u015fimize yaramamaktad\u0131r. Neden? diye sorarsan\u0131z, cevap olarak signal&#8217;lar\u0131n ba\u015flang\u0131\u00e7 de\u011ferlerine g\u00f6re i\u015flem yapmalar\u0131n\u0131 verebiliriz. Yani signal&#8217;lar ilk tan\u0131mland\u0131klar\u0131 de\u011fer neyse ona g\u00f6re i\u015flevsellik g\u00f6stermekte, sonradan de\u011feri de\u011fi\u015fse bile bunla ilgili bir tutum sergilememektedirler. Ee bu a\u00e7\u0131dan bak\u0131ld\u0131\u011f\u0131nda da signal&#8217;lar ile yapt\u0131\u011f\u0131m\u0131z bu tarz \u00e7al\u0131\u015fmalar beklenildi\u011fi gibi tam anlam\u0131 ile reaktif bir davran\u0131\u015f sergilememi\u015f olmaktad\u0131rlar.<\/p>\n<p>Resource API \u00f6zelli\u011finden \u00f6nce bu i\u015flemi beklenildi\u011fi hale getirebilmek i\u00e7in <code>effect<\/code> yap\u0131s\u0131ndan istifade etmemiz gerekmekteydi. <strong>Ee hocam <code>computed<\/code> fonksiyonu da var!<\/strong> dedi\u011finizi duyar gibiyim&#8230; Evet, <code>computed<\/code> fonksiyonu da var, var olmas\u0131na ama <code>computed<\/code> fonksiyonu senkron yap\u0131lar i\u00e7in tasarland\u0131\u011f\u0131ndan genellikle asenkron s\u00fcre\u00e7lerde istemsiz neticelerle s\u00fcreci sonland\u0131rabiliyor. \u015e\u00f6yle ki, <code>...getUserById(1)<\/code> iste\u011finin yap\u0131ld\u0131\u011f\u0131n\u0131 d\u00fc\u015f\u00fcnelim ve sonucunda ge\u00e7 d\u00f6nece\u011fini varsayal\u0131m. Bu istek neticelenmeden \u00fczerine <code>...getUserById(2)<\/code> iste\u011finin yap\u0131ld\u0131\u011f\u0131n\u0131 d\u00fc\u015f\u00fcnelim. \u0130\u015fte bu durumda <code>computed<\/code> fonksiyonu bir \u00f6nceki iste\u011fi iptal etmeyecek ve \u00f6nceki iste\u011fin sonucu sonrakinin ard\u0131ndan gelirse ekrana onun yani \u00f6ncekinin neticesini g\u00f6sterecektir. Ee haliyle bu durumda ne kullan\u0131c\u0131 yapt\u0131\u011f\u0131ndan ne de uygulama hangi state&#8217;de oldu\u011fundan bi\u015fey anlayacakt\u0131r&#8230; \u0130\u015fte buna benzer durumlar <code>computed<\/code> fonksiyonunda s\u00f6z konusu olabilece\u011finden dolay\u0131 bizler <code>effect<\/code> yap\u0131s\u0131n\u0131 kullanarak bu tarz durumlara kar\u015f\u0131n \u00e7\u00f6z\u00fcm getirmeyi daha uygun buluyorduk.<\/p>\n<p>\u015eimdi gelin yukar\u0131daki \u00e7al\u0131\u015fmay\u0131 <em>effect<\/em> ile modifiye edelim;<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nexport class AppComponent {\r\n  userId: WritableSignal&lt;number&gt; = signal&lt;number&gt;(1);\r\n  userList: WritableSignal&lt;User&#x5B;]&gt; = signal&lt;User&#x5B;]&gt;(&#x5B;] as User&#x5B;]);\r\n  userDetail: WritableSignal&lt;User | undefined&gt; = signal&lt;User | undefined&gt;(undefined);\r\n\r\n  userService: UserService = inject(UserService);\r\n\r\n  async ngOnInit() {\r\n    const allUsers: User&#x5B;] = await this.userService.getUsers();\r\n    this.userList.set(allUsers);\r\n  }\r\n\r\n  userSelected(event: any) {\r\n    console.log(event.target.value);\r\n    this.userId.set(event.target.value);\r\n  }\r\n\r\n  \/\/#region effect \u0130le \u00c7\u00f6z\u00fcm\r\n  _userDetail = effect(async () =&gt; {\r\n    const userDetail = await this.userService.getUserById(this.userId());\r\n    this.userDetail.set(userDetail);\r\n  });\r\n  \/\/#endregion\r\n}\r\n<\/pre>\n<\/div>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2025\/02\/Angular-19-resource-API-Ozelligini-Inceleyelim-1.gif\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2025\/02\/Angular-19-resource-API-Ozelligini-Inceleyelim-1.gif\" alt=\"Angular 19 - resource API \u00d6zelli\u011fini \u0130nceleyelim\" width=\"300\" height=\"352\" class=\"alignright size-full wp-image-27536\" \/><\/a>Evet, g\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere mevzu bahis problemin <em>effect<\/em> fonksiyonu sayesinde \u00e7\u00f6z\u00fcld\u00fc\u011f\u00fc d\u00fc\u015f\u00fcn\u00fclebilir, lakin burada bir handikap s\u00f6z konusu. Bu handikap, <em>effect<\/em> i\u00e7erisinde kullan\u0131lan <em>userId<\/em> signal de\u011feri farkl\u0131 bir yerden de\u011fi\u015ftirildi\u011finde ayn\u0131 <em>effect<\/em>&#8216;in tekrar tetiklenmesi durumudur. Bu minvalde yapt\u0131\u011f\u0131m\u0131z \u00e7al\u0131\u015fmaya g\u00f6z atarsak e\u011fer <em>userId<\/em> de\u011feri ba\u015fka gerek\u00e7elerle de\u011fi\u015febilme ihtimaline sahiptir.<\/p>\n<p>\u0130\u015fte bu noktada en ideal \u00e7\u00f6z\u00fcm\u00fc Angular 19 ile birlikte gelen resource API sunabilmektedir. resource API sayesinde bizler signal&#8217;larla yap\u0131lan asenkron s\u00fcre\u00e7leri daha etkin bir \u015fekilde kullanabilmekte ve uygulamay\u0131 yukar\u0131da sim\u00fcle etmeye \u00e7al\u0131\u015ft\u0131\u011f\u0131m\u0131z durumlarda oldu\u011fu gibi reaktif hale getirebilmekteyiz. Bunun i\u00e7in a\u015fa\u011f\u0131daki \u00e7al\u0131\u015fmaya g\u00f6z atarsak e\u011fer;<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nimport { Component, effect, inject, resource, ResourceRef, signal, WritableSignal } from '@angular\/core';\r\nimport { User } from '.\/models\/user';\r\nimport { UserService } from '.\/services\/user.service';\r\nimport { FormsModule } from '@angular\/forms'\r\n\r\n@Component({\r\n  selector: 'app-root',\r\n  imports: &#x5B;FormsModule],\r\n  template: `\r\n    &lt;h4&gt;User List&lt;\/h4&gt;\r\n    &lt;select (change)=&quot;userSelected($event)&quot;&gt;\r\n      @for (user of userList(); track user) {\r\n        &lt;option &#x5B;value]=&quot;user.id&quot;&gt;{{user.name}}&lt;\/option&gt;\r\n      }\r\n    &lt;\/select&gt;\r\n\r\n    &lt;hr&gt;\r\n    @if (userDetail.value()) {\r\n      &lt;label&gt;{{userDetail.value()?.name}}&lt;\/label&gt;\r\n      &lt;label&gt;{{userDetail.value()?.email}}&lt;\/label&gt;\r\n    }\r\n  `\r\n})\r\nexport class AppComponent {\r\n  userId: WritableSignal&lt;number&gt; = signal&lt;number&gt;(1);\r\n  userList: WritableSignal&lt;User&#x5B;]&gt; = signal&lt;User&#x5B;]&gt;(&#x5B;] as User&#x5B;]);\r\n\r\n  \/\/#region resource API \u0130le \u00c7\u00f6z\u00fcm\r\n  userDetail = resource&lt;User, number&gt;({\r\n    request: () =&gt; this.userId(),\r\n    loader: async ({ request: userId }) =&gt; {\r\n      return await this.userService.getUserById(userId);\r\n    }\r\n  })\r\n  \/\/#endregion\r\n\r\n  async ngOnInit() {\r\n    const allUsers: User&#x5B;] = await this.userService.getUsers();\r\n    this.userList.set(allUsers);\r\n  }\r\n\r\n  userService: UserService = inject(UserService);\r\n\r\n  userSelected(event: any) {\r\n    console.log(event.target.value);\r\n    this.userId.set(event.target.value);\r\n  }\r\n}\r\n<\/pre>\n<\/div>\n<p>Evet&#8230; Yukar\u0131daki \u00e7al\u0131\u015fmaya g\u00f6z atarsak e\u011fer resource API ile <em>userId<\/em>&#8216;ye yeni bir de\u011fer atand\u0131\u011f\u0131 her an ilgili kullan\u0131c\u0131ya dair detay iste\u011fi yeniden g\u00f6nderilecek ve elde edilecektir. \u0130\u015fte bu kadar basit. Tabi buradaki i\u015fleyi\u015fi daha net anlayabilmek i\u00e7in bu resource API&#8217;\u0131n anatomik incelemesini daha detayl\u0131 bir \u015fekilde yapmam\u0131z gerekecektir. Bunun i\u00e7in ilgili fonksiyonun yap\u0131s\u0131n\u0131 a\u015fa\u011f\u0131ya sade bir \u015fekilde alal\u0131m;<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nexport declare function resource&lt;T, R&gt;(options: ResourceOptions&lt;T, R&gt;): ResourceRef&lt;T | undefined&gt;;\r\n<\/pre>\n<\/div>\n<p>Dikkat ederseniz, <code>resource<\/code> fonksiyonu esas\u0131nda <code>ResourceOptions<\/code> parametresi alan ve geriye <code>ResourceRef<\/code> t\u00fcr\u00fcnden bir nesne d\u00f6nd\u00fcren fonksiyondur. \u0130lk olarak <code>ResourceOptions<\/code> parametresinin yap\u0131s\u0131n\u0131 incelersek;<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nexport declare interface ResourceOptions&lt;T, R&gt; {\r\n    request?: () =&gt; R;\r\n    loader: ResourceLoader&lt;T, R&gt;;\r\n    .\r\n    .\r\n}\r\n<\/pre>\n<\/div>\n<p>G\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere bu t\u00fcr\u00fcn <em style=\"color:orange;\">request<\/em> ve <em style=\"color:orange;\">loader<\/em> olmak \u00fczere iki ana \u00f6zelli\u011fi mevcuttur. <em style=\"color:orange;\">request<\/em> \u00f6zelli\u011fi, request de\u011ferini temsil eder ve reaktif bir \u015fekilde davran\u0131\u015f sergiler. Bu \u00f6zelli\u011fe verilen de\u011fer de\u011fi\u015fti\u011fi taktirde bu yeni bir request de\u011feri olarak anla\u015f\u0131lacakt\u0131r. Evet, bu davran\u0131\u015f <em>computed<\/em> fonksiyonunun davran\u0131\u015f\u0131n\u0131 an\u0131msatmaktad\u0131r.<\/p>\n<p><em style=\"color:orange;\">loader<\/em> \u00f6zelli\u011fine gelirsek e\u011fer her yeni request de\u011feri \u00fcretildi\u011finde\/geldi\u011finde bu de\u011fer bu fonksiyona iletilmekte ve yeni de\u011fer ile birlikte bu fonksiyon tetiklenmektedir. Dikkat ederseniz bu fonksiyon <code>ResourceLoader<\/code> t\u00fcr\u00fcnde tan\u0131mlanmaktad\u0131r. Yani bir ba\u015fka deyi\u015fle bu fonksiyonu tan\u0131mlarken esas\u0131nda <code>ResourceLoader<\/code> bildiriminde bulunulmaktad\u0131r. Hemen bu t\u00fcr\u00fcn detay\u0131na g\u00f6z atarsak e\u011fer;<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nexport declare type ResourceLoader&lt;T, R&gt; = (param: ResourceLoaderParams&lt;R&gt;) =&gt; PromiseLike&lt;T&gt;;\r\n<\/pre>\n<\/div>\n<p>bunun geriye <code>PromiseLike<\/code> t\u00fcr\u00fcnden bir de\u011fer d\u00f6nd\u00fcren ve <code>ResourceLoaderParams<\/code> t\u00fcr\u00fcnden de parametre alan bir fonksiyon oldu\u011funu g\u00f6r\u00fcyoruz. Bu parametrenin i\u00e7eri\u011fine bakarsak e\u011fer;<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nexport declare interface ResourceLoaderParams&lt;R&gt; {\r\n    request: Exclude&lt;NoInfer&lt;R&gt;, undefined&gt;;\r\n    abortSignal: AbortSignal;\r\n    .\r\n}\r\n<\/pre>\n<\/div>\n<p>\u015feklinde oldu\u011funu g\u00f6rece\u011fiz. Burada <em>request<\/em> \u00f6zelli\u011fi, ad\u0131 \u00fczerinde request yap\u0131lacak de\u011feri ifade etmektedir. <em>abortSignal<\/em> \u00f6zelli\u011fini anlayabilmek i\u00e7in ise resource API&#8217;nin genel davran\u0131\u015f\u0131na hakim olmak gerekmektedir. resource API, <em>request<\/em> de\u011feri de\u011fi\u015fti\u011fi an \u00f6nceki de\u011ferin iste\u011fini iptal eden bir davran\u0131\u015fa sahiptir. \u0130\u015fte bizler bu davran\u0131\u015f s\u00fcrecinde <em>abortSignal<\/em> ile iptal edilen isteklere dair bir d\u00f6n\u00fc\u015f yapabilmekteyiz.<\/p>\n<p>Tabi ayr\u0131ca resource API&#8217;\u0131 iradeli bir \u015fekilde <code>reload<\/code> fonksiyonuyla a\u015fa\u011f\u0131daki gibi tetiklenebilece\u011fini de bilmekte fayda vard\u0131r;<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n.\r\n.\r\n  reload() {\r\n    this.userDetail.reload();\r\n  }\r\n<\/pre>\n<\/div>\n<p>Kimi zaman ayn\u0131 <em>request<\/em> de\u011ferinde tekrar bir y\u00fckleme yap\u0131lmas\u0131 gerekti\u011fi durumlar mevzu bahis olabilmekte ve o taktirde bu fonksiyon imdad\u0131m\u0131za yeti\u015fmektedir.<\/p>\n<p>Son olarak <code>resource<\/code> fonksiyonunun geri d\u00f6n\u00fc\u015f de\u011feri olan <code>ResourceRef<\/code> t\u00fcr\u00fcn\u00fcn detaylar\u0131n\u0131 inceleyelim. Yani resource status&#8217;\u00fc.<\/p>\n<p>Resource status sayesinde, resource API&#8217;\u0131n <em style=\"color:orange;\">loader<\/em> fonksiyonunun asenkron s\u00fcre\u00e7teki durumunu a\u015fa\u011f\u0131daki gibi \u00e7e\u015fitli signal&#8217;larla takip edebilmekteyiz;<\/p>\n<table>\n<thead>\n<tr>\n<th style=\"width:20%;text-align:left;\">\u00d6zellik<\/th>\n<th style=\"text-align:left;\">A\u00e7\u0131klama<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td style=\"text-align:left;\"><strong>value<\/strong><\/td>\n<td style=\"text-align:left;\">resource fonksiyonundan d\u00f6nen de\u011feri ifade eder. E\u011fer asenkron s\u00fcre\u00e7 neticesinde bir de\u011fer d\u00f6nd\u00fcr\u00fclmediyse <em>undefined<\/em> olacakt\u0131r.<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align:left;\"><strong>hasValue<\/strong><\/td>\n<td style=\"text-align:left;\">Hen\u00fcz bir de\u011ferin d\u00f6n\u00fcp d\u00f6nd\u00fcr\u00fclmedi\u011fini ifade eder.<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align:left;\"><strong>error<\/strong><\/td>\n<td style=\"text-align:left;\">resource fonksiyonunun i\u015flev ve yapt\u0131\u011f\u0131 request s\u00fcrecinde varsa bir hata getirecek, yoksa <em>undefined<\/em> d\u00f6necektir.<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align:left;\"><strong>isLoading<\/strong><\/td>\n<td style=\"text-align:left;\">resource fonksiyonunun \u00e7al\u0131\u015f\u0131p, \u00e7al\u0131\u015fmad\u0131\u011f\u0131n\u0131 belirtir.<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align:left;\"><strong>status<\/strong><\/td>\n<td style=\"text-align:left;\">resource&#8217;un state&#8217;ini belirtmektedir.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Haliyle bu \u00f6zellikleri kullanarak resource API \u00fczerinden y\u00fcr\u00fct\u00fclen request&#8217;lerin s\u00fcrecini g\u00f6rsel olarak da html k\u0131sm\u0131na a\u015fa\u011f\u0131daki gibi yans\u0131tabiliriz;<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    @if(!userDetail.hasValue() || userDetail.isLoading()){\r\n      &lt;div&gt;\r\n        Y\u00fckleniyor...\r\n      &lt;\/div&gt;\r\n    }\r\n<\/pre>\n<\/div>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2025\/02\/Angular-19-resource-API-Ozelligini-Inceleyelim-2.gif\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2025\/02\/Angular-19-resource-API-Ozelligini-Inceleyelim-2.gif\" alt=\"Angular 19 - resource API \u00d6zelli\u011fini \u0130nceleyelim\" width=\"300\" height=\"352\" class=\"alignleft size-full wp-image-27544\" \/><\/a>Yap\u0131sal olarak resource API davran\u0131\u015f\u0131n\u0131n <code>switchMap<\/code> semanti\u011fine sahip oldu\u011funu bilmenizde fayda g\u00f6rmekteyim. <code>switchMap<\/code> bir RxJS operat\u00f6r\u00fcd\u00fcr ve \u00f6zellikle nested observable&#8217;lar\u0131 y\u00f6netmek i\u00e7in kullan\u0131lmaktad\u0131r. Yani \u00f6nceki bir observable&#8217;daki s\u00fcreci iptal edip yeni bir observable ba\u015flatmak istiyorsak ya da ba\u015fka bir deyi\u015fle kullan\u0131c\u0131 etkile\u015fimlerindeki sab\u0131rs\u0131zl\u0131klardan kaynakl\u0131 \u00f6nceki i\u015flemlerin iptal edilip en son yap\u0131lan i\u015flemin ge\u00e7erli k\u0131l\u0131nmas\u0131 gerekiyorsa <code>switchMap<\/code> operat\u00f6r\u00fcnden istifade etmekteyiz. Evet, resource API&#8217;de benzer mant\u0131kta bir davran\u0131\u015f benimsemektedir ve \u00f6nceki istekleri her ne kadar iptal etmese de en az\u0131ndan sonu\u00e7lar\u0131n\u0131 yok saymakta ve kullan\u0131c\u0131n\u0131n tela\u015fl\u0131 bir \u015fekilde ekranda yapt\u0131\u011f\u0131 eylemlerden kaynakl\u0131 sistemin \u015firazesiyle oynamamaktad\u0131r \ud83d\ude42<\/p>\n<p>Nihai olarak;<br \/>\nAngular 19 ile gelen resource API \u00f6zelli\u011fi sayesinde, API&#8217;lere g\u00f6nderilecek request s\u00fcre\u00e7lerini olduk\u00e7a etkili bir \u015fekilde reaktif hale getirebildi\u011fimizi ve b\u00f6ylece uygun senaryolarda daha efektif davran\u0131\u015flar sergileyerek olmas\u0131 gereken \u00e7\u00f6z\u00fcm\u00fc olduk\u00e7a pratik bir \u015fekilde uygulayabildi\u011fimizi g\u00f6rm\u00fc\u015f bulunuyoruz. Art\u0131k gerisi projelerimizde bu \u00f6zellikten bol bol istifade ederek maksimum verim almaya kalm\u0131\u015ft\u0131r \ud83d\ude42<\/p>\n<p>\u0130lgilenenlerin faydalanmas\u0131 dile\u011fiyle&#8230;<br \/>\nSonraki yaz\u0131lar\u0131mda g\u00f6r\u00fc\u015fmek \u00fczere&#8230;<br \/>\n\u0130yi \u00e7al\u0131\u015fmalar&#8230;<\/p>\n<!-- AddThis Advanced Settings generic via filter on the_content --><!-- AddThis Share Buttons generic via filter on the_content -->","protected":false},"excerpt":{"rendered":"<p>Merhaba, Bu i\u00e7eri\u011fimizde Angular 19 ile gelen, asenkron veri getirme ve durum y\u00f6netimi i\u015flemlerini daha basit ve efektif hale getiren resource API \u00f6zelli\u011fini inceleyece\u011fiz. resource API Nedir? Resource API&#8217;\u0131 anlamak i\u00e7in en do\u011frusu Angular&#46;&#46;&#46;<!-- AddThis Advanced Settings generic via filter on get_the_excerpt --><!-- AddThis Share Buttons generic via filter on get_the_excerpt --><\/p>\n","protected":false},"author":1,"featured_media":27546,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5216],"tags":[2156,5217,5219,5218],"class_list":["post-27530","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-angular-19","tag-angular","tag-angular-19","tag-angular-19-resource-api","tag-resource-api"],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/27530","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/comments?post=27530"}],"version-history":[{"count":11,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/27530\/revisions"}],"predecessor-version":[{"id":27547,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/27530\/revisions\/27547"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media\/27546"}],"wp:attachment":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media?parent=27530"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/categories?post=27530"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/tags?post=27530"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}