{"id":32170,"date":"2025-10-18T15:01:27","date_gmt":"2025-10-18T12:01:27","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/neden-trpc-ve-next-js-app-router-birlikteligi-onemli\/"},"modified":"2025-10-18T15:01:27","modified_gmt":"2025-10-18T12:01:27","slug":"neden-trpc-ve-next-js-app-router-birlikteligi-onemli","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/neden-trpc-ve-next-js-app-router-birlikteligi-onemli\/","title":{"rendered":"Neden tRPC ve Next.js App Router Birlikteli\u011fi \u00d6nemli?"},"content":{"rendered":"<p><b>Next.js App Router ile tRPC 11 Kurulumu: 2025 Rehberi<\/b><\/p>\n<p>Modern web uygulamalar\u0131 geli\u015ftirmek, hem performans\u0131 hem de geli\u015ftirici deneyimini bir arada sunan g\u00fc\u00e7l\u00fc ara\u00e7lar gerektirir. Peki, u\u00e7tan uca tip g\u00fcvenli\u011fi sa\u011flarken, API geli\u015ftirmenin karma\u015f\u0131kl\u0131\u011f\u0131n\u0131 minimuma indirmek m\u00fcmk\u00fcn m\u00fc? Bu kapsaml\u0131 rehberde, Next.js&#8217;in \u00e7\u0131\u011f\u0131r a\u00e7an App Router&#8217;\u0131 ile tRPC 11&#8217;in nas\u0131l entegre edilece\u011fini ad\u0131m ad\u0131m inceleyece\u011fiz. Geli\u015ftirme s\u00fcrecinizi ba\u015ftan sona d\u00f6n\u00fc\u015ft\u00fcrecek bu g\u00fc\u00e7l\u00fc kombinasyonla, 2025 ve sonras\u0131 i\u00e7in \u00f6l\u00e7eklenebilir ve bak\u0131m\u0131 kolay uygulamalar olu\u015fturman\u0131n kap\u0131lar\u0131n\u0131 aralay\u0131n.<\/p>\n<p>Geli\u015ftiriciler olarak, veri ak\u0131\u015f\u0131n\u0131 y\u00f6netmek, istemci ve sunucu aras\u0131nda g\u00fcvenilir bir ileti\u015fim kurmak her zaman temel zorluklar\u0131m\u0131zdan biri olmu\u015ftur. Geleneksel yakla\u015f\u0131mlar \u00e7o\u011fu zaman bu s\u00fcreci gereksiz yere karma\u015f\u0131k hale getirirken, tRPC ve Next.js App Router&#8217;\u0131n birle\u015fimi adeta bir kurtar\u0131c\u0131 gibi sahneye \u00e7\u0131k\u0131yor. Bu ikilinin sundu\u011fu sinerji, hem geli\u015ftirme h\u0131z\u0131n\u0131 art\u0131r\u0131yor hem de hatalara kar\u015f\u0131 daha diren\u00e7li uygulamalar olu\u015fturman\u0131za olanak tan\u0131yor. \u00d6zellikle 2025 trendlerinde, h\u0131z ve g\u00fcvenilirli\u011fin yan\u0131 s\u0131ra geli\u015ftirici deneyimi de b\u00fcy\u00fck bir \u00f6nem ta\u015f\u0131yor.<\/p>\n<h3>Geleneksel API Yakla\u015f\u0131mlar\u0131n\u0131n Zorluklar\u0131 Nelerdir?<\/h3>\n<p>API geli\u015ftirme d\u00fcnyas\u0131nda REST ve GraphQL gibi standartlar y\u0131llard\u0131r h\u00fck\u00fcm s\u00fcrmektedir. RESTful API&#8217;ler basitlikleri ve geni\u015f destekleri sayesinde yayg\u0131nla\u015fm\u0131\u015f olsa da, \u00f6zellikle b\u00fcy\u00fck ve karma\u015f\u0131k projelerde baz\u0131 dezavantajlar\u0131 bar\u0131nd\u0131r\u0131r. \u00d6rne\u011fin, farkl\u0131 kaynaklar i\u00e7in birden fazla endpoint tan\u0131mlamak gerekebilir ve bu da istemcinin birden \u00e7ok istek yapmas\u0131na yol a\u00e7abilir. Ayr\u0131ca, sunucu ve istemci aras\u0131ndaki veri s\u00f6zle\u015fmelerinin manuel olarak senkronize edilmesi, tip g\u00fcvenli\u011fi eksikli\u011fi nedeniyle run-time hatalar\u0131na davetiye \u00e7\u0131karabilir. Her iki tarafta da ayn\u0131 veri yap\u0131s\u0131n\u0131 sa\u011flamak i\u00e7in genellikle ek ara\u00e7lara veya manuel dok\u00fcmantasyona ihtiya\u00e7 duyulur ki bu da geli\u015ftirme s\u00fcrecini yava\u015flat\u0131r ve hata pay\u0131n\u0131 art\u0131r\u0131r.<\/p>\n<p>GraphQL ise bu sorunlara bir nebze \u00e7\u00f6z\u00fcm getirir. \u0130stemcinin tam olarak ihtiyac\u0131 olan veriyi tek bir istekte \u00e7ekebilmesine olanak tan\u0131r, bu da fazla veri \u00e7ekme (over-fetching) veya eksik veri \u00e7ekme (under-fetching) sorunlar\u0131n\u0131 ortadan kald\u0131r\u0131r. Ancak GraphQL&#8217;in de kendine \u00f6zg\u00fc bir \u00f6\u011frenme e\u011frisi ve karma\u015f\u0131kl\u0131\u011f\u0131 vard\u0131r. \u015eema tan\u0131m\u0131, resolver&#8217;lar ve istemci taraf\u0131nda sorgu yazma pratikleri, projeye yeni ba\u015flayanlar i\u00e7in g\u00f6z korkutucu olabilir. \u00dcstelik, GraphQL ile bile u\u00e7tan uca tip g\u00fcvenli\u011fi sa\u011flamak i\u00e7in Apollo Client veya Relay gibi ek k\u00fct\u00fcphanelerle birlikte \u015fema \u00fcretimi gibi ad\u0131mlar atmak gerekebilir. Bu durum, \u00f6zellikle k\u00fc\u00e7\u00fck ve orta \u00f6l\u00e7ekli projelerde veya prototipleme a\u015famas\u0131nda gereksiz bir y\u00fck olu\u015fturabilir. Her iki yakla\u015f\u0131m da, API katman\u0131n\u0131n ayr\u0131 bir kod taban\u0131nda y\u00f6netilmesini gerektirdi\u011fi i\u00e7in, istemci ve sunucu kodu aras\u0131nda s\u00fcrekli bir ba\u011f kurma ve senkronizasyon ihtiyac\u0131n\u0131 do\u011furur.<\/p>\n<h3>tRPC Nedir ve Ne Sunar?<\/h3>\n<p>tRPC, &#8220;TypeScript Remote Procedure Call&#8221;\u0131n k\u0131saltmas\u0131 olup, temelde TypeScript projeleri i\u00e7in tasarlanm\u0131\u015f bir API geli\u015ftirme \u00e7er\u00e7evesidir. En b\u00fcy\u00fck \u00f6zelli\u011fi, istemci ile sunucu aras\u0131nda otomatik olarak u\u00e7tan uca tip g\u00fcvenli\u011fi sa\u011flamas\u0131d\u0131r. Yani, sunucunuzda bir API prosed\u00fcr\u00fc tan\u0131mlad\u0131\u011f\u0131n\u0131zda, bu prosed\u00fcr\u00fcn t\u00fcm tip bilgileri otomatik olarak istemcinize aktar\u0131l\u0131r ve siz istemci taraf\u0131nda bu prosed\u00fcr\u00fc \u00e7a\u011f\u0131r\u0131rken IDE&#8217;niz size t\u00fcm tip hatalar\u0131n\u0131 an\u0131nda g\u00f6sterir. Bu, geli\u015ftirme s\u00fcrecindeki hatalar\u0131n b\u00fcy\u00fck bir k\u0131sm\u0131n\u0131 derleme zaman\u0131nda yakalaman\u0131z\u0131 sa\u011flar ve run-time hatalar\u0131n\u0131n \u00f6n\u00fcne ge\u00e7er.<\/p>\n<p>tRPC, HTTP katman\u0131na herhangi bir \u015fema veya kod \u00fcretimi gerektirmeden tam tip g\u00fcvenli\u011fi getirir. Bu, geli\u015ftiricilerin sadece TypeScript yazarak g\u00fc\u00e7l\u00fc ve g\u00fcvenli API&#8217;lar olu\u015fturabilece\u011fi anlam\u0131na gelir. &#8220;Zero-bundle&#8221; olmas\u0131, istemciye tRPC&#8217;ye \u00f6zg\u00fc ekstra bir \u00e7al\u0131\u015fma zaman\u0131 kodu g\u00f6ndermedi\u011fi anlam\u0131na gelir; sadece TypeScript tiplerini kullan\u0131r. Bu sayede, uygulaman\u0131z\u0131n ba\u015flang\u0131\u00e7 y\u00fck\u00fc (bundle size) minimumda kal\u0131r. Geli\u015ftirici deneyimi a\u00e7\u0131s\u0131ndan ise tRPC adeta bir r\u00fcya gibidir. IDE&#8217;nizin sundu\u011fu otomatik tamamlama (autocomplete) ve tip kontrol\u00fc sayesinde, sunucu taraf\u0131nda tan\u0131mlad\u0131\u011f\u0131n\u0131z prosed\u00fcrleri istemci taraf\u0131nda kullan\u0131rken sanki yerel bir fonksiyon \u00e7a\u011f\u0131r\u0131yormu\u015f gibi hissedersiniz. Bu ak\u0131c\u0131 deneyim, API geli\u015ftirme s\u00fcrecini \u00e7ok daha h\u0131zl\u0131, keyifli ve hatas\u0131z hale getirir. Sonu\u00e7 olarak, tRPC, modern web geli\u015ftirmenin en b\u00fcy\u00fck sorunlar\u0131ndan biri olan &#8220;client-server type mismatch&#8221; sorununa zarif ve etkili bir \u00e7\u00f6z\u00fcm sunar.<\/p>\n<h3>Next.js App Router&#8217;\u0131n Getirdikleri Nelerdir?<\/h3>\n<p>Next.js 13 ile tan\u0131t\u0131lan App Router, React ekosisteminde bir d\u00f6n\u00fcm noktas\u0131 olarak kabul ediliyor. Bu yeni y\u00f6nlendirme sistemi, React Server Components (RSC) mimarisini merkeze alarak performans\u0131 ve geli\u015ftirme deneyimini bir \u00fcst seviyeye ta\u015f\u0131yor. App Router, sunucuda render edilen bile\u015fenler (Server Components) ile istemcide render edilen bile\u015fenleri (Client Components) bir araya getirerek, her iki taraf\u0131n avantajlar\u0131n\u0131 kullanman\u0131za olanak tan\u0131r. Server Components, sunucuda \u00e7al\u0131\u015farak veri \u00e7ekme, dosya eri\u015fimi veya veritaban\u0131 sorgular\u0131 gibi i\u015flemleri do\u011frudan yapabilir ve bu i\u015flemleri istemciye g\u00f6ndermeden \u00f6nce tamamlar. Bu sayede istemcinin JavaScript y\u00fck\u00fc azal\u0131r ve ilk sayfa y\u00fckleme s\u00fcresi \u00f6nemli \u00f6l\u00e7\u00fcde k\u0131sal\u0131r.<\/p>\n<p>App Router ayr\u0131ca, <code>layout.tsx<\/code>, <code>page.tsx<\/code>, <code>loading.tsx<\/code>, <code>error.tsx<\/code> gibi dosya tabanl\u0131 \u00f6zel bile\u015fenler arac\u0131l\u0131\u011f\u0131yla sezgisel bir dosya sistemi y\u00f6nlendirmesi sunar. Bu yap\u0131, proje organizasyonunu basitle\u015ftirirken, routing mant\u0131\u011f\u0131n\u0131 daha okunur hale getirir. Sunucu Eylemleri (Server Actions) \u00f6zelli\u011fi ise, istemciden do\u011frudan sunucuda \u00e7al\u0131\u015ft\u0131r\u0131labilir fonksiyonlar tan\u0131mlaman\u0131za imkan tan\u0131r, bu da form g\u00f6nderimleri ve veri mutasyonlar\u0131 gibi i\u015flemleri daha g\u00fcvenli ve tip-g\u00fcvenli bir \u015fekilde yapman\u0131z\u0131 sa\u011flar. Next.js App Router&#8217;\u0131n getirdi\u011fi en b\u00fcy\u00fck avantajlardan biri de, veri \u00e7ekme mekanizmalar\u0131n\u0131n optimize edilmi\u015f olmas\u0131d\u0131r. <code>fetch<\/code> API&#8217;sinin geni\u015fletilmi\u015f \u00f6zellikleri ve React&#8217;\u0131n <code>use<\/code> hook&#8217;u sayesinde, asenkron veri \u00e7ekme i\u015flemleri Server Components i\u00e7inde daha do\u011fal ve verimli hale gelir. T\u00fcm bu \u00f6zellikler, Next.js App Router&#8217;\u0131 modern, y\u00fcksek performansl\u0131 ve karma\u015f\u0131k web uygulamalar\u0131 geli\u015ftirmek i\u00e7in ideal bir platform haline getirir.<\/p>\n<h2>tRPC 11 ve Next.js App Router Kurulumuna Ad\u0131m Ad\u0131m Ba\u015flang\u0131\u00e7<\/h2>\n<p>tRPC 11&#8217;i Next.js App Router projenize entegre etmek, ba\u015flang\u0131\u00e7ta biraz g\u00f6z korkutucu gelebilir; ancak do\u011fru ad\u0131mlar\u0131 izledi\u011finizde s\u00fcrecin ne kadar mant\u0131kl\u0131 ve kolay oldu\u011funu g\u00f6receksiniz. Amac\u0131m\u0131z, hem sunucu taraf\u0131nda g\u00fc\u00e7l\u00fc ve tip-g\u00fcvenli bir API olu\u015fturmak hem de bu API&#8217;yi Next.js&#8217;in modern sunucu ve istemci bile\u015fen yap\u0131lar\u0131yla sorunsuz bir \u015fekilde kullanabilmek. Bu b\u00f6l\u00fcmde, projenizi nas\u0131l olu\u015fturaca\u011f\u0131n\u0131zdan tRPC ba\u011f\u0131ml\u0131l\u0131klar\u0131n\u0131 eklemeye, sunucu taraf\u0131 yap\u0131land\u0131rmas\u0131ndan Next.js API rotalar\u0131n\u0131 tan\u0131mlamaya kadar her ad\u0131m\u0131 detayl\u0131ca ele alaca\u011f\u0131z. Bu ad\u0131mlar, projenizin temelini sa\u011flam bir \u015fekilde atarak, ilerideki geli\u015ftirmeleriniz i\u00e7in g\u00fc\u00e7l\u00fc bir zemin haz\u0131rlayacakt\u0131r. Unutmay\u0131n, do\u011fru kurulum, sorunsuz bir geli\u015ftirme deneyiminin anahtar\u0131d\u0131r.<\/p>\n<h3>Proje Olu\u015fturma ve Temel Ba\u011f\u0131ml\u0131l\u0131klar\u0131 Y\u00fckleme<\/h3>\n<p>\u00d6ncelikle Next.js App Router destekli bir proje olu\u015fturarak ba\u015flayaca\u011f\u0131z. Komut sat\u0131r\u0131n\u0131z\u0131 a\u00e7\u0131n ve a\u015fa\u011f\u0131daki komutu \u00e7al\u0131\u015ft\u0131r\u0131n:<\/p>\n<pre><code>\n  <span>npx create-next-app@latest my-trpc-app<\/span>\n<\/pre>\n<p><\/code><\/p>\n<p>Bu komut size birka\u00e7 soru soracakt\u0131r. TypeScript'i ve App Router'\u0131 etkinle\u015ftirdi\u011finizden emin olun:<\/p>\n<ul>\n<li>Would you like to use TypeScript? <b>Yes<\/b><\/li>\n<li>Would you like to use ESLint? Yes<\/li>\n<li>Would you like to use Tailwind CSS? (Opsiyonel, ancak \u00f6nerilir) Yes<\/li>\n<li>Would you like to use <code>src\/<\/code> directory? Yes<\/li>\n<li>Would you like to use App Router? (recommended) <b>Yes<\/b><\/li>\n<li>Would you like to customize the default import alias? No<\/li>\n<\/ul>\n<p>Proje olu\u015fturulduktan sonra, projenizin dizinine gidin:<\/p>\n<pre><code>\n  <span>cd my-trpc-app<\/span>\n<\/pre>\n<p><\/code><\/p>\n<p>\u015eimdi tRPC ve ilgili ba\u011f\u0131ml\u0131l\u0131klar\u0131 y\u00fckleyelim. tRPC, verimli veri \u00e7ekme ve \u00f6nbellekleme i\u00e7in <code>@tanstack\/react-query<\/code>'den faydalan\u0131r. Ayr\u0131ca, API girdilerini do\u011frulamak i\u00e7in <code>zod<\/code> k\u00fct\u00fcphanesini kullanaca\u011f\u0131z:<\/p>\n<pre><code>\n  <span>npm install @trpc\/server @trpc\/client @trpc\/react-query @tanstack\/react-query zod<\/span>\n<\/pre>\n<p><\/code><\/p>\n<p>Bu ba\u011f\u0131ml\u0131l\u0131klar, tRPC sunucunuzu kurmak, istemcinizle ileti\u015fim kurmak ve veri do\u011frulamay\u0131 sa\u011flamak i\u00e7in gerekli temel yap\u0131 ta\u015flar\u0131d\u0131r. <code>@trpc\/client<\/code> ve <code>@trpc\/react-query<\/code> istemci taraf\u0131 i\u00e7in, <code>@trpc\/server<\/code> ise sunucu taraf\u0131 i\u00e7in gereklidir. <code>zod<\/code> ise hem istemci hem de sunucu taraf\u0131nda veri \u015femalar\u0131n\u0131 tan\u0131mlayarak, API'nize g\u00f6nderilen verilerin tip g\u00fcvenli\u011fini ve ge\u00e7erlili\u011fini sa\u011flar. Bu, \u00f6zellikle Next.js App Router ortam\u0131nda, Server Actions veya Client Components arac\u0131l\u0131\u011f\u0131yla veri g\u00f6nderirken kritik \u00f6neme sahiptir. Ba\u011f\u0131ml\u0131l\u0131klar\u0131 y\u00fckledikten sonra, projenizin geli\u015ftirme ortam\u0131 tRPC entegrasyonuna haz\u0131rd\u0131r.<\/p>\n<h3>Sunucu Taraf\u0131 tRPC Yap\u0131land\u0131rmas\u0131 (<code>server\/trpc.ts<\/code> ve <code>server\/routers\/_app.ts<\/code>)<\/h3>\n<p>tRPC'yi Next.js projenize entegre etmenin ilk ad\u0131m\u0131, sunucu taraf\u0131 yap\u0131land\u0131rmas\u0131n\u0131 olu\u015fturmakt\u0131r. <code>src<\/code> dizini alt\u0131nda <code>server<\/code> ad\u0131nda yeni bir klas\u00f6r olu\u015ftural\u0131m. Bu klas\u00f6r tRPC sunucumuzun mant\u0131\u011f\u0131n\u0131 bar\u0131nd\u0131racak.<\/p>\n<p><code>src\/server\/trpc.ts<\/code> dosyas\u0131, tRPC sunucusunun temelini olu\u015fturur. Burada, tRPC router'\u0131m\u0131z\u0131, context'i ve prosed\u00fcrleri (query\/mutation) ba\u015flatmak i\u00e7in gerekli ara\u00e7lar\u0131 tan\u0131mlayaca\u011f\u0131z:<\/p>\n<pre><code>\n  <<span>code<\/span>>\n    <span>import { initTRPC } from '@trpc\/server';<\/span>\n    <span>import { createContext } from '.\/context';<\/span>\n\n    <span>\/**<\/span>\n    <span> * Bu, tRPC sunucumuzun her iste\u011fi i\u00e7in ba\u011flam olu\u015fturmak \u00fczere kullan\u0131lacak i\u015flevdir.<\/span>\n    <span> * Genellikle, kimlik do\u011frulama, veritaban\u0131 ba\u011flant\u0131s\u0131 gibi iste\u011fe \u00f6zel verileri i\u00e7erir.<\/span>\n    <span> *\/<\/span>\n    <span>export const createTRPCContext = createContext;<\/span>\n\n    <span>const t = initTRPC.context<typeof createTRPCContext>().create();<\/span>\n\n    <span>\/**<\/span>\n    <span> * Public bir prosed\u00fcr olu\u015fturmak i\u00e7in kullan\u0131lan bir helper.<\/span>\n    <span> * Bu prosed\u00fcrlere herhangi bir giri\u015f do\u011frulamas\u0131 veya yetkilendirme uygulanmaz.<\/span>\n    <span> *\/<\/span>\n    <span>export const publicProcedure = t.procedure;<\/span>\n    <span>export const router = t.router;<\/span>\n    <span>export const middleware = t.middleware;<\/span>\n  <\/<span>code<\/span>>\n<\/pre>\n<p><\/code><\/p>\n<p>Burada <code>initTRPC.context().create()<\/code> ile tRPC \u00f6rne\u011fini ba\u015flat\u0131yoruz. <code>createTRPCContext<\/code> fonksiyonu ise her istek i\u00e7in bir context olu\u015fturacak. Bu context, veritaban\u0131 ba\u011flant\u0131lar\u0131, kimlik do\u011frulama bilgileri gibi verilere eri\u015fim sa\u011flamak i\u00e7in kullan\u0131l\u0131r. \u015eimdi <code>src\/server\/context.ts<\/code> dosyas\u0131n\u0131 olu\u015ftural\u0131m:<\/p>\n<pre><code>\n  <<span>code<\/span>>\n    <span>import { type inferAsyncReturnType } from '@trpc\/server';<\/span>\n    <span>import { type FetchCreateContextFnOptions } from '@trpc\/server\/adapters\/fetch';<\/span>\n\n    <span>\/**<\/span>\n    <span> * Sunucu taraf\u0131 iste\u011fi i\u00e7in olu\u015fturulan ba\u011flam.<\/span>\n    <span> * Burada herhangi bir iste\u011fe \u00f6zel veri (\u00f6rn: session, db) d\u00f6nd\u00fcrebilirsiniz.<\/span>\n    <span> *\/<\/span>\n    <span>export const createContext = async (opts: FetchCreateContextFnOptions) => {<\/span>\n    <span>  return {<\/span>\n    <span>    \/\/ \u00d6rnek olarak, istek ba\u015fl\u0131klar\u0131na eri\u015febilirsiniz<\/span>\n    <span>    headers: opts.req.headers,<\/span>\n    <span>  };<\/span>\n    <span>};<\/span>\n\n    <span>export type Context = inferAsyncReturnType<typeof createContext>;<\/span>\n  <\/<span>code<\/span>>\n<\/pre>\n<p><\/code><\/p>\n<p>Bu <code>context.ts<\/code> dosyas\u0131, tRPC prosed\u00fcrleriniz i\u00e7inde kullanabilece\u011finiz global verilere eri\u015fim sa\u011flar. \u00d6rne\u011fin, bir kullan\u0131c\u0131n\u0131n kimlik do\u011frulama bilgilerini burada i\u015fleyebilirsiniz.<\/p>\n<p>\u015eimdi tRPC router'lar\u0131m\u0131z\u0131 tan\u0131mlayal\u0131m. Router'lar, API prosed\u00fcrlerinizi d\u00fczenlemenin ve gruplaman\u0131n bir yoludur. <code>src\/server\/routers<\/code> klas\u00f6r\u00fcn\u00fc olu\u015fturun. \u0130\u00e7ine bir <code>_app.ts<\/code> dosyas\u0131 ve \u00f6rnek olarak <code>post.ts<\/code> dosyas\u0131 ekleyelim.<\/p>\n<p><code>src\/server\/routers\/post.ts<\/code>:<\/p>\n<pre><code>\n  <<span>code<\/span>>\n    <span>import { z } from 'zod';<\/span>\n    <span>import { publicProcedure, router } from '..\/trpc';<\/span>\n\n    <span>interface Post {<\/span>\n    <span>  id: string;<\/span>\n    <span>  title: string;<\/span>\n    <span>  content: string;<\/span>\n    <span>}<\/span>\n\n    <span>const posts: Post[] = [<\/span>\n    <span>  { id: '1', title: '\u0130lk Yaz\u0131', content: 'Bu bir deneme yaz\u0131s\u0131d\u0131r.' },<\/span>\n    <span>];<\/span>\n\n    <span>export const postRouter = router({<\/span>\n    <span>  getPosts: publicProcedure<\/span>\n    <span>    .query(() => {<\/span>\n    <span>      return posts;<\/span>\n    <span>    }),<\/span>\n\n    <span>  getPostById: publicProcedure<\/span>\n    <span>    .input(z.object({ id: z.string() }))<\/span>\n    <span>    .query(({ input }) => {<\/span>\n    <span>      return posts.find(post => post.id === input.id);<\/span>\n    <span>    }),<\/span>\n\n    <span>  createPost: publicProcedure<\/span>\n    <span>    .input(z.object({<\/span>\n    <span>      title: z.string().min(5),<\/span>\n    <span>      content: z.string().min(10),<\/span>\n    <span>    }))<\/span>\n    <span>    .mutation(({ input }) => {<\/span>\n    <span>      const newPost: Post = {<\/span>\n    <span>        id: (posts.length + 1).toString(),<\/span>\n    <span>        ...input,<\/span>\n    <span>      };<\/span>\n    <span>      posts.push(newPost);<\/span>\n    <span>      return newPost;<\/span>\n    <span>    }),<\/span>\n    <span>});<\/span>\n  <\/<span>code<\/span>>\n<\/pre>\n<p><\/code><\/p>\n<p>Bu <code>postRouter<\/code>, iki sorgu (<code>getPosts<\/code>, <code>getPostById<\/code>) ve bir mutasyon (<code>createPost<\/code>) tan\u0131ml\u0131yor. <code>zod<\/code> kullanarak girdilerin do\u011frulu\u011funu sa\u011fl\u0131yoruz. \u00d6rne\u011fin, <code>createPost<\/code> mutasyonunda <code>title<\/code> ve <code>content<\/code> alanlar\u0131n\u0131n minimum uzunlukta olmas\u0131n\u0131 zorunlu k\u0131l\u0131yoruz. Bu, API'nize gelen verilerin her zaman beklendi\u011fi gibi olmas\u0131n\u0131 garanti eder.<\/p>\n<p>Son olarak, t\u00fcm router'lar\u0131 birle\u015ftiren ana tRPC router'\u0131n\u0131 <code>src\/server\/routers\/_app.ts<\/code> dosyas\u0131nda olu\u015ftural\u0131m:<\/p>\n<pre><code>\n  <<span>code<\/span>>\n    <span>import { router } from '..\/trpc';<\/span>\n    <span>import { postRouter } from '.\/post';<\/span>\n\n    <span>export const appRouter = router({<\/span>\n    <span>  post: postRouter, \/\/ Post router'\u0131 burada app router'a ekliyoruz<\/span>\n    <span>});<\/span>\n\n    <span>\/\/ \u0130stemci taraf\u0131nda kullan\u0131lacak app router tipi<\/span>\n    <span>export type AppRouter = typeof appRouter;<\/span>\n  <\/<span>code<\/span>>\n<\/pre>\n<p><\/code><\/p>\n<p><code>_app.ts<\/code> dosyas\u0131, t\u00fcm alt router'lar\u0131n\u0131z\u0131 bir araya getiren ana tRPC router'\u0131d\u0131r. <code>AppRouter<\/code> tipi, istemci taraf\u0131nda tip \u00e7\u0131kar\u0131m\u0131 i\u00e7in kritik \u00f6neme sahiptir. Bu yap\u0131land\u0131rma ile sunucu taraf\u0131 tRPC API'nizin temellerini atm\u0131\u015f oldunuz. Art\u0131k Next.js App Router'\u0131n API route'lar\u0131 arac\u0131l\u0131\u011f\u0131yla bu API'yi d\u0131\u015f d\u00fcnyaya a\u00e7abiliriz.<\/p>\n<h3>Next.js API Route Olu\u015fturma (<code>app\/api\/trpc\/[trpc]\/route.ts<\/code>)<\/h3>\n<p>Next.js App Router'da, API rotalar\u0131 da dosya sistemi tabanl\u0131d\u0131r ve <code>app\/api<\/code> dizini alt\u0131nda tan\u0131mlan\u0131r. tRPC sunucumuzu Next.js uygulamam\u0131zla entegre etmek i\u00e7in \u00f6zel bir API route dosyas\u0131 olu\u015fturaca\u011f\u0131z. Bu dosya, t\u00fcm tRPC isteklerini tRPC sunucumuza y\u00f6nlendirecek bir k\u00f6pr\u00fc g\u00f6revi g\u00f6recek.<\/p>\n<p><code>src\/app\/api\/trpc\/[trpc]\/route.ts<\/code> yolunda bir dosya olu\u015ftural\u0131m. K\u00f6\u015feli parantezler <code>[trpc]<\/code> dinamik bir rota segmenti oldu\u011funu g\u00f6sterir ve gelen tRPC isteklerinin farkl\u0131 prosed\u00fcrlere y\u00f6nlendirilmesini sa\u011flar.<\/p>\n<pre><code>\n  <<span>code<\/span>>\n    <span>import { fetchRequestHandler } from '@trpc\/server\/adapters\/fetch';<\/span>\n    <span>import { appRouter, createTRPCContext } from '@\/server'; \/\/ appRouter ve context'i i\u00e7e aktar\u0131n<\/span>\n\n    <span>const handler = (req: Request) =><\/span>\n    <span>  fetchRequestHandler({<\/span>\n    <span>    endpoint: '\/api\/trpc',<\/span>\n    <span>    req,<\/span>\n    <span>    router: appRouter,<\/span>\n    <span>    createContext: createTRPCContext,<\/span>\n    <span>  });<\/span>\n\n    <span>export { handler as GET, handler as POST };<\/span>\n  <\/<span>code<\/span>>\n<\/pre>\n<p><\/code><\/p>\n<p>Burada <code>@trpc\/server\/adapters\/fetch<\/code> i\u00e7indeki <code>fetchRequestHandler<\/code>'\u0131 kullan\u0131yoruz. Bu handler, gelen HTTP isteklerini al\u0131r, tRPC context'ini olu\u015fturur ve iste\u011fi <code>appRouter<\/code>'daki ilgili tRPC prosed\u00fcr\u00fcne y\u00f6nlendirir. <code>endpoint: &#039;\/api\/trpc&#039;<\/code> tRPC istemcinizin istek g\u00f6nderece\u011fi URL'i tan\u0131mlar. Son olarak, bu <code>handler<\/code>'\u0131 hem <code>GET<\/code> hem de <code>POST<\/code> istekleri i\u00e7in d\u0131\u015fa aktar\u0131yoruz, \u00e7\u00fcnk\u00fc tRPC hem sorgular (<code>GET<\/code>) hem de mutasyonlar (<code>POST<\/code>) i\u00e7in bu handler'\u0131 kullan\u0131r. Bu ad\u0131m, Next.js uygulaman\u0131z\u0131n tRPC API'nizle ileti\u015fim kurmas\u0131n\u0131 sa\u011flayan temel ba\u011flant\u0131y\u0131 kurar. Art\u0131k sunucu taraf\u0131n\u0131z haz\u0131r ve istemci taraf\u0131nda bu API'yi kullanmaya ba\u015flayabiliriz.<\/p>\n<div class=\"interactive-tip\">\n  <b>Uzman \u0130pucu:<\/b> <code>appRouter<\/code> ve <code>createTRPCContext<\/code> import yolunun <code>server<\/code> klas\u00f6r\u00fcn\u00fc hedefledi\u011finden emin olun. Genellikle <code>src\/server\/index.ts<\/code> gibi bir dosya olu\u015fturup t\u00fcm \u00f6nemli server taraf\u0131 tRPC dosyalar\u0131n\u0131 buradan export etmek, import yollar\u0131n\u0131 daha d\u00fczenli hale getirir. \u00d6rne\u011fin <code>src\/server\/index.ts<\/code> i\u00e7eri\u011fi \u015f\u00f6yle olabilir: <\/p>\n<pre><code><span>export * from '.\/trpc';<\/span><span>export * from '.\/context';<\/span><span>export * from '.\/routers\/_app';<\/span><\/pre>\n<p><\/code> Bu durumda yukar\u0131daki import <code>import { appRouter, createTRPCContext } from &#039;@\/server&#039;;<\/code> \u015feklinde daha temiz olacakt\u0131r.\n<\/div>\n<h2>\u0130stemci Taraf\u0131nda tRPC Kullan\u0131m\u0131 ve Ger\u00e7ek D\u00fcnya Senaryolar\u0131<\/h2>\n<p>Sunucu taraf\u0131 tRPC API'mizi ba\u015far\u0131yla kurdu\u011fumuza g\u00f6re, \u015fimdi bu g\u00fc\u00e7l\u00fc API'yi Next.js istemci bile\u015fenlerimizde ve hatta sunucu bile\u015fenlerimizde nas\u0131l kullanaca\u011f\u0131m\u0131z\u0131 \u00f6\u011frenme zaman\u0131. tRPC'nin ger\u00e7ek g\u00fcc\u00fc, istemci taraf\u0131nda sundu\u011fu u\u00e7tan uca tip g\u00fcvenli\u011fi ve <code>@tanstack\/react-query<\/code> ile entegrasyonu sayesinde ortaya \u00e7\u0131kar. Bu b\u00f6l\u00fcm, tRPC istemcisini nas\u0131l yap\u0131land\u0131raca\u011f\u0131n\u0131zdan, veri \u00e7ekme ve g\u00fcncelleme i\u015flemlerini nas\u0131l yapaca\u011f\u0131n\u0131za, ve k\u00fc\u00e7\u00fck bir blog uygulamas\u0131 \u00fczerinden ger\u00e7ek d\u00fcnya senaryolar\u0131na kadar geni\u015f bir yelpazeyi kapsayacak. Performans optimizasyonlar\u0131 ve \u00f6nbellekleme stratejileri ile uygulaman\u0131z\u0131n h\u0131z\u0131n\u0131 ve duyarl\u0131l\u0131\u011f\u0131n\u0131 nas\u0131l art\u0131rabilece\u011finizi de detayl\u0131ca inceleyece\u011fiz.<\/p>\n<h3>tRPC \u0130stemcisi Olu\u015fturma ve Provider Yap\u0131land\u0131rmas\u0131<\/h3>\n<p>\u0130stemci taraf\u0131nda tRPC kullanabilmek i\u00e7in \u00f6ncelikle bir tRPC istemcisi olu\u015fturmal\u0131 ve bu istemciyi Next.js uygulaman\u0131z\u0131n k\u00f6k bile\u015fenine sa\u011flamal\u0131s\u0131n\u0131z. Bunun i\u00e7in <code>src\/lib<\/code> dizini alt\u0131nda <code>trpc.ts<\/code> ad\u0131nda bir dosya olu\u015ftural\u0131m. Bu dosya, tRPC istemcisini yap\u0131land\u0131racak ve <code>@tanstack\/react-query<\/code> ile entegrasyonu sa\u011flayacakt\u0131r.<\/p>\n<p><code>src\/lib\/trpc.ts<\/code>:<\/p>\n<pre><code>\n  <<span>code<\/span>>\n    <span>import { httpBatchLink, loggerLink } from '@trpc\/client';<\/span>\n    <span>import { createTRPCReact } from '@trpc\/react-query';<\/span>\n    <span>import { type AppRouter } from '@\/server\/routers\/_app';<\/span>\n    <span>import superjson from 'superjson';<\/span>\n\n    <span>export const trpc = createTRPCReact<AppRouter>();<\/span>\n\n    <span>\/\/ \u0130stemci taraf\u0131nda kullanmak \u00fczere bir tRPC istemcisi olu\u015fturun<\/span>\n    <span>export const createClient = () =><\/span>\n    <span>  trpc.createClient({<\/span>\n    <span>    transformer: superjson, \/\/ Tarih, Map, Set gibi tipleri serile\u015ftirmek i\u00e7in<\/span>\n    <span>    links: [<\/span>\n    <span>      loggerLink({<\/span>\n    <span>        enabled: (opts) =><\/span>\n    <span>          process.env.NODE_ENV === 'development' ||<\/span>\n    <span>          (opts.direction === 'down' && opts.result instanceof Error),<\/span>\n    <span>      }),<\/span>\n    <span>      httpBatchLink({<\/span>\n    <span>        url: 'http:\/\/localhost:3000\/api\/trpc', \/\/ tRPC API endpoint'iniz<\/span>\n    <span>      }),<\/span>\n    <span>    ],<\/span>\n    <span>  });<\/span>\n  <\/<span>code<\/span>>\n<\/pre>\n<p><\/code><\/p>\n<p>Bu dosyada <code>createTRPCReact<AppRouter>()<\/code> ile tRPC istemcisini olu\u015fturuyoruz. <code>AppRouter<\/code> tipini sunucu taraf\u0131nda tan\u0131mlad\u0131\u011f\u0131m\u0131z <code>_app.ts<\/code> dosyas\u0131ndan i\u00e7e aktard\u0131\u011f\u0131m\u0131z i\u00e7in, bu, istemci taraf\u0131nda da otomatik tip g\u00fcvenli\u011fi sa\u011flar. <code>createClient<\/code> fonksiyonu, <code>superjson<\/code> kullanarak karma\u015f\u0131k tipleri serile\u015ftirir ve <code>httpBatchLink<\/code> ile API endpoint'ini belirtir. <code>loggerLink<\/code> ise geli\u015ftirme ortam\u0131nda konsola tRPC isteklerini loglamaya yarar.<\/p>\n<p>\u015eimdi bu istemciyi Next.js uygulaman\u0131z\u0131n <code>app\/layout.tsx<\/code> dosyas\u0131nda sa\u011flayarak t\u00fcm bile\u015fenlerinizin tRPC'ye eri\u015fmesini sa\u011flayal\u0131m. <code>src\/app\/layout.tsx<\/code> dosyas\u0131 tipik olarak t\u00fcm uygulaman\u0131z\u0131 sarmalayan k\u00f6k layout'tur. Burada, <code>@tanstack\/react-query<\/code> i\u00e7in <code>QueryClientProvider<\/code> ve tRPC i\u00e7in <code>trpc.Provider<\/code>'\u0131 kullanaca\u011f\u0131z. Ancak bu provider'lar istemci bile\u015fenleri oldu\u011fu i\u00e7in, bunlar\u0131 sarmalayan bir client component olu\u015fturmam\u0131z gerekecek.<\/p>\n<p><code>src\/app\/trpc-provider.tsx<\/code> (Client Component):<\/p>\n<pre><code>\n  <<span>code<\/span>>\n    <span>'use client';<\/span>\n\n    <span>import { QueryClient, QueryClientProvider } from '@tanstack\/react-query';<\/span>\n    <span>import { loggerLink, httpBatchLink } from '@trpc\/client';<\/span>\n    <span>import { useState } from 'react';<\/span>\n    <span>import { trpc } from '@\/lib\/trpc';<\/span>\n    <span>import superjson from 'superjson';<\/span>\n\n    <span>export function TRPCProvider({ children }: { children: React.ReactNode }) {<\/span>\n    <span>  const [queryClient] = useState(() => new QueryClient());<\/span>\n    <span>  const [trpcClient] = useState(() =><\/span>\n    <span>    trpc.createClient({<\/span>\n    <span>      transformer: superjson,<\/span>\n    <span>      links: [<\/span>\n    <span>        loggerLink({<\/span>\n    <span>          enabled: (opts) =><\/span>\n    <span>            process.env.NODE_ENV === 'development' ||<\/span>\n    <span>            (opts.direction === 'down' && opts.result instanceof Error),<\/span>\n    <span>        }),<\/span>\n    <span>        httpBatchLink({<\/span>\n    <span>          url: <code>${process.env.NEXT_PUBLIC_BASE_URL ?? &#039;http:\/\/localhost:3000&#039;}\/api\/trpc<\/code>,<\/span>\n    <span>        }),<\/span>\n    <span>      ],<\/span>\n    <span>    }),<\/span>\n    <span>  );<\/span>\n\n    <span>  return (<\/span>\n    <span>    <QueryClientProvider client={queryClient}><\/span>\n    <span>      <trpc.Provider client={trpcClient} queryClient={queryClient}><\/span>\n    <span>        {children}<\/span>\n    <span>      <\/trpc.Provider><\/span>\n    <span>    <\/QueryClientProvider><\/span>\n    <span>  );<\/span>\n    <span>}<\/span>\n  <\/<span>code<\/span>>\n<\/pre>\n<p><\/code><\/p>\n<p>Bu <code>TRPCProvider<\/code> bile\u015feni, <code>QueryClient<\/code> ve tRPC istemcisini <code>useState<\/code> hook'lar\u0131 ile ba\u015flat\u0131r ve t\u00fcm alt bile\u015fenlerine sa\u011flar. Endpoint'i ortam de\u011fi\u015fkeni (<code>NEXT_PUBLIC_BASE_URL<\/code>) ile dinamik hale getirmeyi unutmay\u0131n. \u015eimdi <code>src\/app\/layout.tsx<\/code> dosyas\u0131n\u0131 g\u00fcncelleyelim:<\/p>\n<pre><code>\n  <<span>code<\/span>>\n    <span>import '.\/globals.css';<\/span>\n    <span>import { TRPCProvider } from '.\/trpc-provider';<\/span>\n\n    <span>export default function RootLayout({<\/span>\n    <span>  children,<\/span>\n    <span>}: {<\/span>\n    <span>  children: React.ReactNode;<\/span>\n    <span>}) {<\/span>\n    <span>  return (<\/span>\n    <span>    <html lang=\"en\"><\/span>\n    <span>      <body><\/span>\n    <span>        <TRPCProvider><\/span>\n    <span>          {children}<\/span>\n    <span>        <\/TRPCProvider><\/span>\n    <span>      <\/body><\/span>\n    <span>    <\/html><\/span>\n    <span>  );<\/span>\n    <span>}<\/span>\n  <\/<span>code<\/span>>\n<\/pre>\n<p><\/code><\/p>\n<p>Bu ad\u0131mlar, uygulaman\u0131z\u0131n tRPC istemcisini ve React Query'yi kullanmaya haz\u0131r oldu\u011funu garanti eder. Art\u0131k herhangi bir client component'tan tRPC prosed\u00fcrlerinizi \u00e7a\u011f\u0131rabilirsiniz.<\/p>\n<h3>Veri \u00c7ekme (Queries) ve Veri G\u00fcncelleme (Mutations)<\/h3>\n<p>tRPC, <code>@tanstack\/react-query<\/code> ile entegre \u00e7al\u0131\u015ft\u0131\u011f\u0131 i\u00e7in, veri \u00e7ekme ve g\u00fcncelleme i\u015flemleri olduk\u00e7a sezgiseldir. <code>useQuery<\/code> hook'unu kullanarak veri \u00e7ekebilir, <code>useMutation<\/code> hook'unu kullanarak veri g\u00fcncelleyebilirsiniz. Bu hook'lar, y\u00fckleme durumlar\u0131, hata y\u00f6netimi ve \u00f6nbellekleme gibi bir\u00e7ok \u00f6zelli\u011fi otomatik olarak ele al\u0131r.<\/p>\n<p>\u015eimdi bir <code>src\/app\/page.tsx<\/code> dosyas\u0131nda veya herhangi bir client component'ta tRPC prosed\u00fcrlerimizi nas\u0131l kullanaca\u011f\u0131m\u0131za dair bir \u00f6rnek olu\u015ftural\u0131m.<\/p>\n<p><code>src\/app\/page.tsx<\/code> (Client Component olarak i\u015faretleyelim):<\/p>\n<pre><code>\n  <<span>code<\/span>>\n    <span>'use client';<\/span>\n\n    <span>import { trpc } from '@\/lib\/trpc';<\/span>\n    <span>import { useState } from 'react';<\/span>\n\n    <span>export default function HomePage() {<\/span>\n    <span>  \/\/ T\u00fcm postlar\u0131 \u00e7ekmek i\u00e7in useQuery kullan\u0131n<\/span>\n    <span>  const { data: posts, isLoading, error } = trpc.post.getPosts.useQuery();<\/span>\n\n    <span>  \/\/ Yeni post olu\u015fturmak i\u00e7in useMutation kullan\u0131n<\/span>\n    <span>  const createPostMutation = trpc.post.createPost.useMutation({<\/span>\n    <span>    onSuccess: () => {<\/span>\n    <span>      alert('Post ba\u015far\u0131yla olu\u015fturuldu!');<\/span>\n    <span>      \/\/ Post listesini yenilemek i\u00e7in cache'i ge\u00e7ersiz k\u0131l\u0131n<\/span>\n    <span>      trpc.post.getPosts.invalidate(); <\/span>\n    <span>    },<\/span>\n    <span>    onError: (err) => {<\/span>\n    <span>      alert(<code>Hata olu\u015ftu: ${err.message}<\/code>);<\/span>\n    <span>    },<\/span>\n    <span>  });<\/span>\n\n    <span>  const [title, setTitle] = useState('');<\/span>\n    <span>  const [content, setContent] = useState('');<\/span>\n\n    <span>  const handleSubmit = (e: React.FormEvent) => {<\/span>\n    <span>    e.preventDefault();<\/span>\n    <span>    createPostMutation.mutate({ title, content });<\/span>\n    <span>    setTitle('');<\/span>\n    <span>    setContent('');<\/span>\n    <span>  };<\/span>\n\n    <span>  if (isLoading) return <div>Y\u00fckleniyor...<\/div>;<\/span>\n    <span>  if (error) return <div>Hata: {error.message}<\/div>;<\/span>\n\n    <span>  return (<\/span>\n    <span>    <main style={{ padding: '20px' }}><\/span>\n    <span>      <h1>Blog Yaz\u0131lar\u0131<\/h1><\/span>\n\n    <span>      {\/* Yeni Post Olu\u015fturma Formu *\/}<\/span>\n    <span>      <form onSubmit={handleSubmit} style={{ marginBottom: '30px', border: '1px solid #ccc', padding: '15px', borderRadius: '8px' }}><\/span>\n    <span>        <h2>Yeni Post Olu\u015ftur<\/h2><\/span>\n    <span>        <div style={{ marginBottom: '10px' }}><\/span>\n    <span>          <label htmlFor=\"title\" style={{ display: 'block', marginBottom: '5px' }}>Ba\u015fl\u0131k:<\/label><\/span>\n    <span>          <input<\/span>\n    <span>            id=\"title\"<\/span>\n    <span>            type=\"text\"<\/span>\n    <span>            value={title}<\/span>\n    <span>            onChange={(e) => setTitle(e.target.value)}<\/span>\n    <span>            required<\/span>\n    <span>            style={{ width: '100%', padding: '8px', borderRadius: '4px', border: '1px solid #ddd' }}<\/span>\n    <span>          \/><\/span>\n    <span>        <\/div><\/span>\n    <span>        <div style={{ marginBottom: '15px' }}><\/span>\n    <span>          <label htmlFor=\"content\" style={{ display: 'block', marginBottom: '5px' }}>\u0130\u00e7erik:<\/label><\/span>\n    <span>          <textarea<\/span>\n    <span>            id=\"content\"<\/span>\n    <span>            value={content}<\/span>\n    <span>            onChange={(e) => setContent(e.target.value)}<\/span>\n    <span>            required<\/span>\n    <span>            rows={4}<\/span>\n    <span>            style={{ width: '100%', padding: '8px', borderRadius: '4px', border: '1px solid #ddd' }}<\/span>\n    <span>          \/><\/span>\n    <span>        <\/div><\/span>\n    <span>        <button type=\"submit\" disabled={createPostMutation.isLoading}<\/span>\n    <span>                style={{ padding: '10px 15px', borderRadius: '4px', border: 'none', backgroundColor: '#0070f3', color: 'white', cursor: 'pointer' }}><\/span>\n    <span>          {createPostMutation.isLoading ? 'Olu\u015fturuluyor...' : 'Post Olu\u015ftur'}<\/span>\n    <span>        <\/button><\/span>\n    <span>      <\/form><\/span>\n\n    <span>      {\/* Post Listesi *\/}<\/span>\n    <span>      <ul style={{ listStyle: 'none', padding: 0 }}><\/span>\n    <span>        {posts?.map((post) => (<\/span>\n    <span>          <li key={post.id} style={{ border: '1px solid #eee', padding: '15px', marginBottom: '10px', borderRadius: '8px' }}><\/span>\n    <span>            <h3>{post.title}<\/h3><\/span>\n    <span>            <p>{post.content}<\/p><\/span>\n    <span>            <small>ID: {post.id}<\/small><\/span>\n    <span>          <\/li><\/span>\n    <span>        ))}<\/span>\n    <span>      <\/ul><\/span>\n    <span>    <\/main><\/span>\n    <span>  );<\/span>\n    <span>}<\/span>\n  <\/<span>code<\/span>>\n<\/pre>\n<p><\/code><\/p>\n<p>Bu \u00f6rnekte, <code>trpc.post.getPosts.useQuery()<\/code> ile t\u00fcm blog yaz\u0131lar\u0131n\u0131 \u00e7ekiyoruz. <code>isLoading<\/code> ve <code>error<\/code> durumlar\u0131n\u0131 kolayca y\u00f6netebiliyoruz. <code>createPostMutation<\/code> ise <code>trpc.post.createPost.useMutation<\/code> ile yeni bir yaz\u0131 olu\u015fturmak i\u00e7in kullan\u0131l\u0131yor. <code>onSuccess<\/code> callback'inde <code>trpc.post.getPosts.invalidate()<\/code> \u00e7a\u011f\u0131rarak, yeni bir yaz\u0131 eklendi\u011finde mevcut yaz\u0131 listesinin \u00f6nbelle\u011fini ge\u00e7ersiz k\u0131l\u0131yoruz ve b\u00f6ylece liste otomatik olarak g\u00fcncelleniyor. Bu yakla\u015f\u0131m, kullan\u0131c\u0131 aray\u00fcz\u00fcn\u00fcz\u00fcn her zaman g\u00fcncel kalmas\u0131n\u0131 sa\u011flarken, gereksiz API isteklerini minimumda tutar. tRPC'nin en b\u00fcy\u00fck avantajlar\u0131ndan biri de buradaki tip g\u00fcvenli\u011fidir; <code>posts<\/code> dizisinin elemanlar\u0131 otomatik olarak <code>Post<\/code> tipinde tan\u0131n\u0131r ve <code>createPostMutation.mutate<\/code> fonksiyonuna g\u00f6nderilen <code>title<\/code> ve <code>content<\/code> alanlar\u0131n\u0131n tipleri de sunucuda tan\u0131mlad\u0131\u011f\u0131m\u0131z <code>zod<\/code> \u015femas\u0131na uygun olmak zorundad\u0131r. Aksi takdirde, TypeScript derleyici hatas\u0131 al\u0131rs\u0131n\u0131z, bu da run-time hatalar\u0131n\u0131 \u00f6nemli \u00f6l\u00e7\u00fcde azalt\u0131r.<\/p>\n<h3>Vaka Analizi: K\u00fc\u00e7\u00fck Bir Blog Uygulamas\u0131<\/h3>\n<p>Yukar\u0131daki kod blo\u011fu asl\u0131nda k\u00fc\u00e7\u00fck bir blog uygulamas\u0131 i\u00e7in temel CRUD operasyonlar\u0131n\u0131n nas\u0131l yap\u0131laca\u011f\u0131na dair harika bir \u00f6rnekti. Daha da ileri giderek, Next.js Server Components ile tRPC'yi nas\u0131l kullanabilece\u011finizi g\u00f6steren bir senaryoya bakal\u0131m. Server Components do\u011frudan tRPC istemcisiyle etkile\u015fime giremez, \u00e7\u00fcnk\u00fc tRPC istemcisi browser API'leri gibi client-side ortam gerektirir. Ancak tRPC'nin g\u00fcc\u00fcn\u00fc Server Components'ta kullanman\u0131n bir yolu var: Do\u011frudan sunucu taraf\u0131 router'\u0131 \u00e7a\u011f\u0131rmak veya \u00f6zel bir sunucu taraf\u0131 tRPC istemcisi olu\u015fturmak.<\/p>\n<p><code>src\/server\/trpc.server.ts<\/code> ad\u0131nda bir dosya olu\u015ftural\u0131m. Bu dosya, sadece sunucu bile\u015fenlerinde kullan\u0131lacak bir tRPC istemcisi g\u00f6revi g\u00f6recek:<\/p>\n<pre><code>\n  <<span>code<\/span>>\n    <span>import { appRouter, createTRPCContext } from '@\/server';<\/span>\n\n    <span>\/\/ Server Components i\u00e7inde tRPC prosed\u00fcrlerini \u00e7a\u011f\u0131rmak i\u00e7in bir helper<\/span>\n    <span>export const serverTrpc = appRouter.createCaller(createTRPCContext({<\/span>\n    <span>  \/\/ Server Components i\u00e7inde Request nesnesine do\u011frudan eri\u015fim olmad\u0131\u011f\u0131 i\u00e7in<\/span>\n    <span>  \/\/ bo\u015f bir ba\u015fl\u0131k nesnesi g\u00f6nderebilir veya ihtiyac\u0131n\u0131za g\u00f6re doldurabilirsiniz.<\/span>\n    <span>  req: new Request('http:\/\/localhost:3000'), <\/span>\n    <span>  res: new Response(),<\/span>\n    <span>}));<\/span>\n  <\/<span>code<\/span>>\n<\/pre>\n<p><\/code><\/p>\n<p>Burada <code>appRouter.createCaller()<\/code> kullanarak tRPC prosed\u00fcrlerimizi do\u011frudan sunucu taraf\u0131nda \u00e7a\u011f\u0131rabilece\u011fimiz bir nesne olu\u015fturuyoruz. <code>createTRPCContext<\/code>'e g\u00f6nderilen <code>req<\/code> ve <code>res<\/code> nesneleri, Next.js'in API route handler'\u0131nda tRPC'nin bekledi\u011fi yap\u0131ya uygun bir sim\u00fclasyon sa\u011fl\u0131yor.<\/p>\n<p>\u015eimdi <code>src\/app\/static-posts\/page.tsx<\/code> ad\u0131nda yeni bir Server Component olu\u015ftural\u0131m ve burada <code>serverTrpc<\/code>'yi kullanarak g\u00f6nderileri direkt sunucuda \u00e7ekelim:<\/p>\n<pre><code>\n  <<span>code<\/span>>\n    <span>import { serverTrpc } from '@\/server\/trpc.server';<\/span>\n    <span>import Link from 'next\/link';<\/span>\n\n    <span>export default async function StaticPostsPage() {<\/span>\n    <span>  const posts = await serverTrpc.post.getPosts();<\/span>\n\n    <span>  return (<\/span>\n    <span>    <div style={{ padding: '20px' }}><\/span>\n    <span>      <h1>Static Blog Yaz\u0131lar\u0131 (Server Component)<\/h1><\/span>\n    <span>      <p>Bu g\u00f6nderiler, sayfa sunucuda render edilirken do\u011frudan tRPC sunucusundan \u00e7ekildi.<\/p><\/span>\n    <span>      <ul style={{ listStyle: 'none', padding: 0 }}><\/span>\n    <span>        {posts.map((post) => (<\/span>\n    <span>          <li key={post.id} style={{ border: '1px solid #eee', padding: '15px', marginBottom: '10px', borderRadius: '8px' }}><\/span>\n    <span>            <h3>{post.title}<\/h3><\/span>\n    <span>            <p>{post.content}<\/p><\/span>\n    <span>            <Link href={<code>\/static-posts\/${post.id}<\/code>} style={{ color: '#0070f3', textDecoration: 'none' }}><\/span>\n    <span>              Devam\u0131n\u0131 oku<\/span>\n    <span>            <\/Link><\/span>\n    <span>          <\/li><\/span>\n    <span>        ))}<\/span>\n    <span>      <\/ul><\/span>\n    <span>    <\/div><\/span>\n    <span>  );<\/span>\n    <span>}<\/span>\n  <\/<span>code<\/span>>\n<\/pre>\n<p><\/code><\/p>\n<p>Bu <code>StaticPostsPage<\/code> bir Server Component oldu\u011fu i\u00e7in, <code>async<\/code> bir fonksiyon olarak tan\u0131mlan\u0131r ve <code>await serverTrpc.post.getPosts()<\/code> \u00e7a\u011fr\u0131s\u0131n\u0131 do\u011frudan sunucuda yapar. Bu sayede, istemciye sadece HTML g\u00f6nderilir ve ilk y\u00fckleme performans\u0131 art\u0131r\u0131l\u0131r. Bu yakla\u015f\u0131m, statik i\u00e7erik veya ilk y\u00fcklemede g\u00f6sterilmesi gereken veriler i\u00e7in idealdir. Server Components, tRPC ile birlikte kullan\u0131ld\u0131\u011f\u0131nda, uygulaman\u0131z\u0131n performans\u0131n\u0131 ve kullan\u0131c\u0131 deneyimini \u00f6nemli \u00f6l\u00e7\u00fcde art\u0131rabilir.<\/p>\n<h3>Performans Optimizasyonlar\u0131 ve \u00d6nbellekleme<\/h3>\n<p>tRPC'nin <code>@tanstack\/react-query<\/code> ile olan entegrasyonu, performans optimizasyonlar\u0131 ve \u00f6nbellekleme konusunda size g\u00fc\u00e7l\u00fc ara\u00e7lar sunar. <code>@tanstack\/react-query<\/code> (eski ad\u0131yla React Query), veri \u00e7ekme, \u00f6nbellekleme, senkronizasyon ve sunucu durumu y\u00f6netimini basitle\u015ftirir.<\/p>\n<p><strong>Otomatik \u00d6nbellekleme ve <code>stale-while-revalidate<\/code>:<\/strong><br \/>\n<code>useQuery<\/code> hook'u, verileri otomatik olarak \u00f6nbelle\u011fe al\u0131r. Varsay\u0131lan olarak, bir sorgu \"stale\" (eskimi\u015f) kabul edildikten sonra, kullan\u0131c\u0131 aray\u00fcz\u00fcnde mevcut \u00f6nbelle\u011fe al\u0131nm\u0131\u015f veri g\u00f6sterilirken arka planda yeni veri \u00e7ekilir (stale-while-revalidate). Bu, kullan\u0131c\u0131n\u0131n her zaman an\u0131nda bir yan\u0131t almas\u0131n\u0131 ve uygulaman\u0131n duyarl\u0131 kalmas\u0131n\u0131 sa\u011flar.<\/p>\n<p><strong>Manuel \u00d6nbellek Y\u00f6netimi:<\/strong><br \/>\nYukar\u0131daki <code>createPostMutation<\/code> \u00f6rne\u011finde g\u00f6rd\u00fc\u011f\u00fcn\u00fcz gibi, bir mutasyon ba\u015far\u0131l\u0131 oldu\u011funda <code>trpc.post.getPosts.invalidate()<\/code> \u00e7a\u011f\u0131rarak ilgili sorgunun \u00f6nbelle\u011fini manuel olarak ge\u00e7ersiz k\u0131labiliriz. Bu, uygulaman\u0131n yeni verileri otomatik olarak tekrar \u00e7ekmesini ve UI'\u0131 g\u00fcncellemesini sa\u011flar.<\/p>\n<p><strong>Batching (Toplu \u0130stekler):<\/strong><br \/>\ntRPC'nin <code>httpBatchLink<\/code> \u00f6zelli\u011fi, ayn\u0131 render d\u00f6ng\u00fcs\u00fcnde yap\u0131lan birden fazla tRPC iste\u011fini tek bir HTTP iste\u011finde birle\u015ftirerek a\u011f trafi\u011fini ve gecikmeyi azalt\u0131r. Bu, \u00f6zellikle bir\u00e7ok farkl\u0131 veriyi ayn\u0131 anda \u00e7ekmeniz gereken durumlarda performans\u0131 art\u0131r\u0131r.<\/p>\n<p><strong>Veri Prefetching:<\/strong><br \/>\nKullan\u0131c\u0131 bir sayfay\u0131 ziyaret etmeden \u00f6nce verileri \u00f6nceden \u00e7ekerek y\u00fckleme s\u00fcrelerini daha da k\u0131saltabilirsiniz. Next.js'in <code>Link<\/code> bile\u015feni, ba\u011flant\u0131n\u0131n \u00fczerine gelindi\u011finde hedef sayfan\u0131n verilerini otomatik olarak \u00f6nceden getirebilir. tRPC ve <code>react-query<\/code> ile bunu daha da optimize edebilirsiniz. \u00d6rne\u011fin, bir liste sayfas\u0131nda, detay sayfalar\u0131n\u0131n verilerini kullan\u0131c\u0131 listenin \u00fczerine geldi\u011finde \u00f6nceden \u00e7ekmek m\u00fcmk\u00fcnd\u00fcr.<\/p>\n<p><strong>Mobil Uyumlu HTML ve Duyarl\u0131 Tasar\u0131m:<\/strong><br \/>\nPerformans sadece API h\u0131z\u0131ndan ibaret de\u011fildir, ayn\u0131 zamanda kullan\u0131c\u0131 aray\u00fcz\u00fcn\u00fcn (UI) duyarl\u0131l\u0131\u011f\u0131 ve farkl\u0131 cihazlarda iyi g\u00f6r\u00fcnmesi de \u00f6nemlidir. Next.js, mobil uyumlu tasar\u0131mlar i\u00e7in CSS mod\u00fclleri veya Tailwind CSS gibi ara\u00e7larla kolayca entegre olur. \u00d6rne\u011fin, CSS media query'lerini kullanarak farkl\u0131 ekran boyutlar\u0131na g\u00f6re stilleri ayarlayabilirsiniz:<\/p>\n<pre><code>\n  <<span>code<\/span>>\n    <span>\/* src\/app\/globals.css *\/<\/span>\n    <span>.container {<\/span>\n    <span>  padding: 20px;<\/span>\n    <span>}<\/span>\n\n    <span>@media (max-width: 768px) {<\/span>\n    <span>  .container {<\/span>\n    <span>    padding: 10px;<\/span>\n    <span>  }<\/span>\n\n    <span>  h1 {<\/span>\n    <span>    font-size: 1.5em;<\/span>\n    <span>  }<\/span>\n\n    <span>  ul li {<\/span>\n    <span>    margin-bottom: 5px;<\/span>\n    <span>    padding: 10px;<\/span>\n    <span>  }<\/span>\n    <span>}<\/span>\n  <\/<span>code<\/span>>\n<\/pre>\n<p><\/code><\/p>\n<p>Bu basit CSS \u00f6rne\u011fi, 768px geni\u015fli\u011fin alt\u0131ndaki ekranlarda padding'i azalt\u0131r ve ba\u015fl\u0131k boyutunu k\u00fc\u00e7\u00fclt\u00fcr. tRPC ile h\u0131zl\u0131 ve tip-g\u00fcvenli API'lar geli\u015ftirirken, Next.js'in sundu\u011fu responsive tasar\u0131m yeteneklerini kullanarak kullan\u0131c\u0131lar\u0131n\u0131za t\u00fcm cihazlarda harika bir deneyim sunmay\u0131 unutmay\u0131n. Bu optimizasyonlar bir araya geldi\u011finde, uygulaman\u0131z\u0131n hem backend hem de frontend taraf\u0131nda \u00fcst d\u00fczey performans sergilemesini sa\u011flar.<\/p>\n<h2>Sonu\u00e7 ve S\u0131k\u00e7a Sorulan Sorular<\/h2>\n<p>Next.js App Router ile tRPC 11 entegrasyonu, modern web geli\u015ftirmenin en g\u00fc\u00e7l\u00fc ve verimli yakla\u015f\u0131mlar\u0131ndan birini sunar. Bu rehber boyunca, tRPC'nin sundu\u011fu u\u00e7tan uca tip g\u00fcvenli\u011finden, Next.js App Router'\u0131n getirdi\u011fi performans avantajlar\u0131na kadar bir\u00e7ok konuyu ele ald\u0131k. Proje olu\u015fturma, sunucu ve istemci taraf\u0131 yap\u0131land\u0131rmalar\u0131, veri \u00e7ekme ve g\u00fcncelleme i\u015flemleri gibi pratik ad\u0131mlarla, bu g\u00fc\u00e7l\u00fc kombinasyonu kendi projelerinizde nas\u0131l uygulayaca\u011f\u0131n\u0131z\u0131 \u00f6\u011frendiniz.<\/p>\n<h3>Gelece\u011fe Y\u00f6nelik Bak\u0131\u015f<\/h3>\n<p>tRPC ve Next.js App Router'\u0131n birlikte kullan\u0131m\u0131, \u00f6zellikle TypeScript ekosisteminde geli\u015ftirme yapanlar i\u00e7in oyunun kurallar\u0131n\u0131 yeniden yaz\u0131yor. 2025 ve sonras\u0131nda, geli\u015ftirici deneyimi, performans ve g\u00fcvenilirli\u011fin \u00f6nemi artmaya devam edecek. tRPC'nin s\u0131f\u0131r \u00e7al\u0131\u015fma zaman\u0131 ek y\u00fck\u00fc, otomatik tip g\u00fcvenli\u011fi ve <code>@tanstack\/react-query<\/code> ile kusursuz entegrasyonu, API katman\u0131ndaki bir\u00e7ok karma\u015f\u0131kl\u0131\u011f\u0131 ortadan kald\u0131r\u0131yor. Next.js App Router ise React Server Components, Sunucu Eylemleri ve optimize edilmi\u015f veri \u00e7ekme mekanizmalar\u0131yla, uygulamalar\u0131n\u0131z\u0131n hem h\u0131zl\u0131 hem de \u00f6l\u00e7eklenebilir olmas\u0131n\u0131 sa\u011fl\u0131yor.<\/p>\n<p>Bu kombinasyon, daha az kodla daha fazlas\u0131n\u0131 yapman\u0131za, hatalar\u0131 derleme zaman\u0131nda yakalaman\u0131za ve bu sayede daha sa\u011flam ve bak\u0131m\u0131 kolay uygulamalar geli\u015ftirmenize olanak tan\u0131r. \u00d6zellikle b\u00fcy\u00fck ekiplerde ve h\u0131zla b\u00fcy\u00fcyen projelerde, tRPC'nin tip g\u00fcvenli\u011fi, geli\u015ftiricilerin farkl\u0131 mod\u00fcller \u00fczerinde paralel \u00e7al\u0131\u015f\u0131rken tutarl\u0131l\u0131\u011f\u0131 korumas\u0131na yard\u0131mc\u0131 olur. Next.js'in gelecekteki geli\u015ftirmeleriyle birlikte, bu entegrasyonun daha da sorunsuz ve g\u00fc\u00e7l\u00fc hale gelmesi beklenmektedir. Bu teknoloji y\u0131\u011f\u0131n\u0131n\u0131 benimseyerek, web geli\u015ftirmenin gelece\u011fine \u015fimdiden yat\u0131r\u0131m yapm\u0131\u015f olursunuz.<\/p>\n<h3>S\u0131k\u00e7a Sorulan Sorular (SSS)<\/h3>\n<table style=\"width:100%; border-collapse: collapse; margin-top: 20px;\">\n<thead>\n<tr style=\"background-color: #f2f2f2;\">\n<th style=\"border: 1px solid #ddd; padding: 8px; text-align: left;\">Soru<\/th>\n<th style=\"border: 1px solid #ddd; padding: 8px; text-align: left;\">Cevap<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td style=\"border: 1px solid #ddd; padding: 8px;\">tRPC sadece TypeScript ile mi \u00e7al\u0131\u015f\u0131r?<\/td>\n<td style=\"border: 1px solid #ddd; padding: 8px;\">Evet, tRPC'nin temel avantaj\u0131 olan u\u00e7tan uca tip g\u00fcvenli\u011fi, TypeScript'in derleme zaman\u0131 kontrollerinden faydalan\u0131r. Bu nedenle, tRPC kullanmak i\u00e7in projenizin TypeScript ile yaz\u0131lmas\u0131 gerekmektedir.<\/td>\n<\/tr>\n<tr>\n<td style=\"border: 1px solid #ddd; padding: 8px;\">B\u00fcy\u00fck projelerde tRPC kullan\u0131m\u0131 i\u00e7in \u00f6nerileriniz var m\u0131?<\/td>\n<td style=\"border: 1px solid #ddd; padding: 8px;\">B\u00fcy\u00fck projelerde tRPC'nin g\u00fcc\u00fc daha da ortaya \u00e7\u0131kar. Router'lar\u0131n\u0131z\u0131 mant\u0131ksal gruplara ay\u0131rarak (<code>postRouter<\/code>, <code>userRouter<\/code> vb.) y\u00f6netilebilirli\u011fi art\u0131rabilirsiniz. Ayr\u0131ca, farkl\u0131 tRPC router'lar\u0131n\u0131 birden fazla sunucu dosyas\u0131na yayarak kod taban\u0131n\u0131z\u0131 daha mod\u00fcler hale getirebilirsiniz. Middleware kullanarak yetkilendirme ve do\u011frulama gibi ortak i\u015flemleri merkezi bir \u015fekilde y\u00f6netmek de b\u00fcy\u00fck projeler i\u00e7in \u00f6nemlidir.<\/td>\n<\/tr>\n<tr>\n<td style=\"border: 1px solid #ddd; padding: 8px;\">Next.js Server Components ile tRPC nas\u0131l entegre edilir?<\/td>\n<td style=\"border: 1px solid #ddd; padding: 8px;\">Server Components do\u011frudan client-side tRPC istemcisini kullanamaz. Bunun yerine, <code>appRouter.createCaller()<\/code> metodunu kullanarak sunucu taraf\u0131nda tRPC prosed\u00fcrlerini do\u011frudan \u00e7a\u011f\u0131rabilirsiniz. Bu yakla\u015f\u0131m, verilerin sunucuda \u00e7ekilip istemciye sadece HTML olarak g\u00f6nderilmesini sa\u011flar, bu da ilk y\u00fckleme performans\u0131n\u0131 art\u0131r\u0131r.<\/td>\n<\/tr>\n<tr>\n<td style=\"border: 1px solid #ddd; padding: 8px;\">tRPC REST veya GraphQL'in yerine tamamen ge\u00e7ebilir mi?<\/td>\n<td style=\"border: 1px solid #ddd; padding: 8px;\">tRPC, \u00f6zellikle ayn\u0131 kod taban\u0131nda (monorepo) veya ayn\u0131 geli\u015ftirme ekibinin hem frontend hem de backend'i y\u00f6netti\u011fi durumlarda harika bir alternatiftir. Ancak, \u00fc\u00e7\u00fcnc\u00fc taraf API'larla entegrasyon, mobil uygulamalar veya \u00e7ok farkl\u0131 teknolojilerin kullan\u0131ld\u0131\u011f\u0131 da\u011f\u0131n\u0131k mimariler i\u00e7in REST veya GraphQL hala daha uygun olabilir. tRPC, \"e\u011fer TypeScript kullan\u0131yorsan\u0131z ve ayn\u0131 dilde end-to-end tip g\u00fcvenli\u011fi istiyorsan\u0131z\" m\u00fckemmeldir.<\/td>\n<\/tr>\n<tr>\n<td style=\"border: 1px solid #ddd; padding: 8px;\">tRPC'de kimlik do\u011frulama (authentication) ve yetkilendirme (authorization) nas\u0131l yap\u0131l\u0131r?<\/td>\n<td style=\"border: 1px solid #ddd; padding: 8px;\">tRPC, bu t\u00fcr i\u015flemler i\u00e7in custom middleware mekanizmas\u0131 sunar. <code>createTRPCContext<\/code> i\u00e7inde kullan\u0131c\u0131 bilgilerini alabilir (\u00f6rne\u011fin JWT token'\u0131 parse ederek) ve middleware kullanarak belirli prosed\u00fcrlere eri\u015fimi kontrol edebilirsiniz. Yetkilendirme i\u00e7in ise, prosed\u00fcr\u00fcn i\u00e7inde kullan\u0131c\u0131 rol\u00fcn\u00fc kontrol eden basit bir <code>if<\/code> ko\u015fulu veya ayr\u0131 bir helper fonksiyonu kullanabilirsiniz.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n","protected":false},"excerpt":{"rendered":"Next.js App Router ile tRPC 11 Kurulumu: 2025 Rehberi Modern web uygulamalar\u0131 geli\u015ftirmek, hem performans\u0131 hem de geli\u015ftirici&hellip;","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":[1469],"tags":[],"class_list":{"0":"post-32170","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-nextjs","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>Neden tRPC ve Next.js App Router Birlikteli\u011fi \u00d6nemli?<\/title>\n<meta name=\"description\" content=\"{post.content}\" \/>\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\/neden-trpc-ve-next-js-app-router-birlikteligi-onemli\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Neden tRPC ve Next.js App Router Birlikteli\u011fi \u00d6nemli?\" \/>\n<meta property=\"og:description\" content=\"{post.content}\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/neden-trpc-ve-next-js-app-router-birlikteligi-onemli\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2025-10-18T12:01:27+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=\"25 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/neden-trpc-ve-next-js-app-router-birlikteligi-onemli\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/neden-trpc-ve-next-js-app-router-birlikteligi-onemli\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"Neden tRPC ve Next.js App Router Birlikteli\u011fi \u00d6nemli?\",\"datePublished\":\"2025-10-18T12:01:27+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/neden-trpc-ve-next-js-app-router-birlikteligi-onemli\/\"},\"wordCount\":3966,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"articleSection\":[\"NextJS\"],\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/neden-trpc-ve-next-js-app-router-birlikteligi-onemli\/#respond\"]}],\"copyrightYear\":\"2025\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/neden-trpc-ve-next-js-app-router-birlikteligi-onemli\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/neden-trpc-ve-next-js-app-router-birlikteligi-onemli\/\",\"name\":\"Neden tRPC ve Next.js App Router Birlikteli\u011fi \u00d6nemli?\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2025-10-18T12:01:27+00:00\",\"description\":\"{post.content}\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/neden-trpc-ve-next-js-app-router-birlikteligi-onemli\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/neden-trpc-ve-next-js-app-router-birlikteligi-onemli\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/neden-trpc-ve-next-js-app-router-birlikteligi-onemli\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Neden tRPC ve Next.js App Router Birlikteli\u011fi \u00d6nemli?\"}]},{\"@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":"Neden tRPC ve Next.js App Router Birlikteli\u011fi \u00d6nemli?","description":"{post.content}","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\/neden-trpc-ve-next-js-app-router-birlikteligi-onemli\/","og_locale":"tr_TR","og_type":"article","og_title":"Neden tRPC ve Next.js App Router Birlikteli\u011fi \u00d6nemli?","og_description":"{post.content}","og_url":"https:\/\/fatihsoysal.com\/blog\/neden-trpc-ve-next-js-app-router-birlikteligi-onemli\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2025-10-18T12:01:27+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"25 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/neden-trpc-ve-next-js-app-router-birlikteligi-onemli\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/neden-trpc-ve-next-js-app-router-birlikteligi-onemli\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"Neden tRPC ve Next.js App Router Birlikteli\u011fi \u00d6nemli?","datePublished":"2025-10-18T12:01:27+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/neden-trpc-ve-next-js-app-router-birlikteligi-onemli\/"},"wordCount":3966,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"articleSection":["NextJS"],"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/neden-trpc-ve-next-js-app-router-birlikteligi-onemli\/#respond"]}],"copyrightYear":"2025","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/neden-trpc-ve-next-js-app-router-birlikteligi-onemli\/","url":"https:\/\/fatihsoysal.com\/blog\/neden-trpc-ve-next-js-app-router-birlikteligi-onemli\/","name":"Neden tRPC ve Next.js App Router Birlikteli\u011fi \u00d6nemli?","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2025-10-18T12:01:27+00:00","description":"{post.content}","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/neden-trpc-ve-next-js-app-router-birlikteligi-onemli\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/neden-trpc-ve-next-js-app-router-birlikteligi-onemli\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/neden-trpc-ve-next-js-app-router-birlikteligi-onemli\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Neden tRPC ve Next.js App Router Birlikteli\u011fi \u00d6nemli?"}]},{"@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\/32170","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=32170"}],"version-history":[{"count":0,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/32170\/revisions"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=32170"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=32170"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=32170"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}