مشکل رایج در APIهای سنتی
در معماریهای معمول مثل REST یا GraphQL معمولاً با این چالش روبهرو هستیم:
- تعریف مدل داده در Backend
- تعریف مجدد همان مدل در Frontend
- احتمال ناسازگاری بین دو طرف
- نیاز به Schema یا قرارداد جداگانه
مثلاً:
Backend:
User {
id: number
name: string
}
Frontend باید همان مدل را دوباره تعریف کند.
اگر یکی از آنها تغییر کند، ممکن است خطاهای runtime ایجاد شود.
tRPC چیست؟
tRPC یک کتابخانه برای TypeScript است که اجازه میدهد:
Frontend مستقیماً توابع Backend را به صورت type-safe فراخوانی کند.
بدون نیاز به:
- REST endpoints
- GraphQL schema
- OpenAPI
در واقع TypeScript خودش قرارداد API میشود.
ایده اصلی tRPC
به جای تعریف endpointها، شما procedure تعریف میکنید.
مثال ساده:
Backend
const appRouter = router({
getUser: publicProcedure
.input(z.string())
.query(({ input }) => {
return db.user.findById(input)
}),
})
Frontend
const user = await trpc.getUser.query("123")
ویژگی مهم:
اگر نوع داده تغییر کند، TypeScript در هر دو سمت خطا میدهد.
مزایای اصلی tRPC
Type Safety کامل
تمام درخواستها و پاسخها توسط TypeScript بررسی میشوند.
بدون نیاز به:
- Swagger
- GraphQL schema
- manual typings
حذف Overfetching
برخلاف REST، داده دقیقاً همان چیزی است که درخواست شده.
توسعه سریعتر
نیازی به ساخت:
- Controller
- DTO
- API docs
نیست.
یک تابع مینویسید و قابل استفاده در frontend میشود.
هماهنگی کامل Frontend و Backend
وقتی مدل داده تغییر کند:
TypeScript فوراً تمام خطاها را نشان میدهد.
معماری tRPC
ساختار معمول پروژه:
/server router.ts procedures.ts /client trpc.ts components
Router در Backend تعریف میشود و type آن به Frontend منتقل میشود.
ترکیب محبوب tRPC در اکوسیستم مدرن
tRPC معمولاً با این ابزارها استفاده میشود:
- Next.js
- React
- TanStack Query
- Zod برای validation
این ترکیب یک full-stack type-safe stack ایجاد میکند.
مثال کامل ساده
Backend
import { initTRPC } from '@trpc/server'
const t = initTRPC.create()
export const appRouter = t.router({
hello: t.procedure.query(() => {
return { message: "Hello world" }
}),
})
Frontend
const result = await trpc.hello.query() console.log(result.message)
TypeScript دقیقاً میداند خروجی چیست.
چه زمانی tRPC بهترین انتخاب است؟
tRPC مناسب پروژههایی است که:
- full-stack TypeScript دارند
- Frontend و Backend در یک codebase هستند
- تیم توسعه کوچک یا متوسط است
- سرعت توسعه مهم است
چه زمانی مناسب نیست؟
در برخی سناریوها tRPC انتخاب ایدهآلی نیست:
- API عمومی برای third-party ها
- سیستمهایی با چند زبان برنامهنویسی
- microserviceهای مستقل
- نیاز به API documentation عمومی
در این موارد REST یا GraphQL بهتر هستند.
جمعبندی
tRPC یکی از جذابترین ابزارهای اکوسیستم TypeScript است که توسعه API را بسیار سادهتر میکند.
با استفاده از tRPC میتوان:
- APIهای کاملاً type-safe ساخت
- از duplication بین frontend و backend جلوگیری کرد
- سرعت توسعه را افزایش داد
- خطاهای runtime را کاهش داد
این رویکرد مخصوصاً در اپلیکیشنهای مدرن React و Next.js بسیار محبوب شده و به عنوان یکی از الگوهای جدید full-stack TypeScript development شناخته میشود.
هنوز دیدگاهی ثبت نشده
اولین نفری باشید که نظر میدهد!