tRPC serveri konstruktor kimi yığılır: initTRPC hazırlıq yaradır, router procedure-ləri toplayır, procedure isə addımlar zəncirdir (giriş yoxlaması, middleware, sizin kodunuz), adapter isə hamısını HTTP-yə qoşur. Bu dərsdə hər hissəni qeydlər serveri nümunəsində araşdıracağıq — modulun sonunda məhz bu server layihəyə çevriləcək.
Kontekst: hər procedure-ə nə lazımdır
Hər sorğunun öz «əşyaları» var: verilənlər bazasına qoşulma, kimin daxil olduğu haqqında məlumat, başlıqlar. Bütün bunlar kontekstdə (ctx) toplanır — hər sorğu üçün yenidən yaradılan və hər procedure-ə düşən obyektdə. Bənzətmə: ofisdə ziyarətçi nişanı. Hər ziyarətçinin (sorğunun) nişanı fərdidir, hər əməkdaş (procedure) kiminlə işlədiyini anlamaq üçün ona baxır.
// server/context.ts
import { db } from './db';
import { getUserId } from './auth'; // your own function: session, JWT, cookie
export async function createContext(opts: { headers: Headers }) {
return {
db,
userId: await getUserId(opts.headers), // string | null
};
}
export type Context = Awaited<ReturnType<typeof createContext>>;getUserId-in içində nə olması sizdən asılıdır: Auth.js sessiyası, başlıqdakı JWT, cookie. Kontekstin tipini TypeScript funksiyanın qaytardığı dəyərdən götürür — onu əllə yazmaq lazım deyil.
💡 Next.js üçün tRPC sənədlərində belə funksiya
createTRPCContextadlanır. Amma eyni adlı funksiya@trpc/tanstack-react-query-də də var, ona görə kursda öz funksiyamızıcreateContextadlandırırıq — qarışmamaq üçün.
initTRPC: serverin hazırlığı
// server/trpc.ts
import { initTRPC } from '@trpc/server';
import type { Context } from './context';
const t = initTRPC.context<Context>().create();
export const router = t.router;
export const publicProcedure = t.procedure;
export const createCallerFactory = t.createCallerFactory;initTRPC.context<Context>().create() t obyektini yaradır — tikinti hissələri dəsti. Biz yalnız lazım olanları ixrac edirik: router (procedure-ləri toplayır), publicProcedure (istənilən şəxsin çağıra biləcəyi procedure) və createCallerFactory (serverdə çağırışlar və testlər üçün lazım olacaq). t-nin özünü kənara vermirik ki, bütün fayllar eyni dəstdən istifadə etsin.
Procedure-lər: query və mutation
Procedure — konveyerdir: çağırış addımlardan ardıcıl keçir və istənilən addım onu xəta ilə dayandıra bilər.
Procedure zəncirlə yığılır: publicProcedure-dən başlayırıq, addımlar əlavə edirik (.input(...), .use(...)) və .query(...) ya da .mutation(...) ilə bitiririk — bu, resolver-dir, yəni sizin funksiyanızdır.