- tRPC फुलस्टैक TypeScript ऐप्स में TypeScript inference साझा करता है, जिससे सर्वर और क्लाइंट के बीच API type mismatch कम होता है
- सर्वर API बदलने पर उसका असर क्लाइंट कोड में तुरंत TypeScript errors और autocomplete के जरिए दिख जाता है, जिससे refactoring का बोझ घटता है
- यह अलग schema या code generation चरण के बिना काम करता है, इसलिए build process या runtime overhead बढ़ाए बिना type-safe API बनाई जा सकती है
- यह React, Next.js, Express, Fastify, AWS Lambda, Solid, Svelte जैसी कई JavaScript environments के लिए adapters देता है
- इसका बुनियादी flow है procedures define करना, HTTP server बनाना, और
AppRoutertype देकर client connect करना; इसका लक्ष्य API server code को SDK की तरह इस्तेमाल करने वाला developer experience देना है
tRPC API development का तरीका कैसे बदलता है
- tRPC फुलस्टैक applications में सर्वर और क्लाइंट को एक ही TypeScript type information इस्तेमाल करने देता है, जिससे productivity बढ़ती है
- इसका मुख्य उद्देश्य end-to-end type-safe API को आसानी से बनाना और पारंपरिक API layers में होने वाले दोहराव वाले काम को कम करना है
- अगर सर्वर-साइड बदलाव का असर क्लाइंट usage पर पड़ता है, तो TypeScript errors के जरिए बता देता है, जिससे क्लाइंट-सर्वर boundary पर type mismatch जल्दी पकड़ा जा सकता है
डेवलपर्स को महसूस होने वाली मुख्य खूबियां
-
automatic type safety
- सर्वर-साइड बदलाव का असर क्लाइंट कोड पर पड़े तो वह TypeScript errors के रूप में दिखता है
-
तेज developer experience
- tRPC में कोई build या compile चरण नहीं है
- इसे code generation, runtime overhead, या अलग build process के बिना इस्तेमाल किया जा सकता है
-
framework independence
- इसे JavaScript frameworks और runtimes की पूरी रेंज में इस्तेमाल किया जा सकता है
- मौजूदा projects में भी इसे आसानी से जोड़ा जा सकता है
-
autocomplete
- यह API server code को SDK की तरह संभालने का अनुभव देता है
- endpoints इस्तेमाल करते समय type-based hints मिलते हैं
-
छोटा client footprint
- tRPC में कोई dependencies नहीं हैं और इसका client-side size छोटा है
-
included adapters
- यह React, Next.js, Express, Fastify, AWS Lambda, Solid, Svelte आदि के लिए adapters देता है
बुनियादी उपयोग प्रवाह
- tRPC API की शुरुआत पहले procedure define करने से होती है
- procedure backend बनाने वाले functions होते हैं, जिन्हें compose किया जा सकता है और query, mutation, subscription के रूप में बनाया जा सकता है
- कई procedures को एक router में बांधा जाता है
-
procedure define करना
- उदाहरण में
initTRPC.create()से tRPC instance बनाया जाता है, औरrouterवpublicProcedureतैयार किए जाते हैं greetingprocedure input के रूप मेंnamestring लेता है औरHello ${input.name}के रूप में string लौटाता है- input validation के लिए Zod का उपयोग किया जाता है, ताकि क्लाइंट input ठीक उसी रूप में हो जिसकी procedure को अपेक्षा है
- फ़ाइल के अंत में
export type AppRouter = typeof appRouter;से router type export किया जाता है, ताकि उसे frontend code में इस्तेमाल किया जा सके
- उदाहरण में
-
HTTP server बनाना
createHTTPServerकोappRouterदेकर tRPC server चलाया जाता है- उदाहरण में API को port
3000पर listen कराने के लिएlisten(3000)कॉल किया जाता है - tRPC Next.js, Express, Fetch API आधारित environments, Fastify, AWS Lambda, और vanilla Node HTTP server के लिए adapters देता है
- Fetch API आधारित environments के उदाहरणों में Astro, Remix, SvelteKit, Cloudflare Workers शामिल हैं
-
client connect करना और query चलाना
- सर्वर चलने के बाद
createTRPCClient<AppRouter>से client बनाया जाता है और data query किया जा सकता है - उदाहरण client
httpBatchLinkका उपयोग करकेhttp://localhost:3000से जुड़ता है trpc.greeting.query({ name: 'John' })जैसी call से सर्वर कीgreetingprocedure इस्तेमाल की जा सकती है- client बनाते समय
AppRoutertype देने पर backend API से मेल खाने वाला TypeScript autocomplete और IntelliSense बिना code generation के मिल जाता है
- सर्वर चलने के बाद
शुरुआत के templates और बनाने का उद्देश्य
- सीधे आज़माने के लिए Use this template उपलब्ध है
- tRPC के निर्माता ने इसे पारंपरिक API layers की ज़रूरत कम करने और तेज़ iteration के साथ ऐप के न टूटने का भरोसा देने के लिए बनाया था
- tRPC का उपयोग अग्रणी तकनीकी टीमें और कई Fortune 500 कंपनियां कर रही हैं
डेवलपर प्रतिक्रियाएं
- कई डेवलपर उद्धरणों में tRPC को code quality, delivery speed, developer satisfaction, क्लाइंट-सर्वर boundary refactoring, input validation, और typed middleware experience बेहतर करने वाले टूल के रूप में आंका गया है
- TypeScript monorepo में इसे plain REST या GraphQL की तुलना में अधिक सरल लेकिन मजबूत typing देने वाले विकल्प के रूप में देखा जाता है
- एक उपयोग मामला भी बताया गया है जिसमें सर्वर से Stripe API payload लौटाने पर भी React components में response data types मिल जाते हैं
1 टिप्पणियां
Hacker News की राय
अभी हमारे codebase से tRPC हटाने का काम चल रहा है, और tight coupling की वजह से यह किसी बुरे सपने जैसा था
एक पहलू यह भी था कि junior developers को interfaces या data access patterns के बारे में सोचने से बचने के लिए प्रेरित करता था, और Prisma से components तक सीधी mapping बन गई थी
तेज़ prototyping के लिए यह शानदार है, लेकिन बाद में codebase को अलग-अलग हिस्सों में बाँटने की कोशिश करें तो आप जल्दी ही dead end में फँस जाते हैं
यह TypeScript के बाहर की languages तक भी scale होता है, इसलिए backend को किसी दूसरी language में ले जाने या Swift, Kotlin जैसे native mobile clients बनाने में भी मदद करता है
tRPC बहुत अच्छा है, लेकिन आखिरकार यह backend और frontend के बीच सिर्फ transport layer ही है
tRPC के internal structure को business logic के अंदर गहराई तक इस्तेमाल होने देना उतना ही खराब है जितना input, schema और separation को साफ़-साफ़ define करने वाली controller या router layer का न होना
इसलिए बाद में tRPC छोड़ना भी अपेक्षाकृत आसान होगा, और उदाहरण के लिए किसी पूरे subsystem को queue पर चलाने के लिए move करना भी मुश्किल नहीं लगता
ऐसी चीज़ों की learning curve होती है, और आम तौर पर शुरुआत
type FunctionIWroteTodayArgs = …जैसे बेकार और कुछ भी explain न करने वाले types से होती हैकुछ iterations के बाद धीरे-धीरे समझ आता है कि लक्ष्य code को duplicate करना नहीं, बल्कि domain को explain करना और reusable व उपयोगी types, interfaces और APIs बनाना है
इसलिए tRPC को हटाने के बजाय team के साथ मिलकर उस हिस्से को बेहतर करना सही लगता है
server side पर HTTP client declare करना और client side पर उसे consume करना क्यों ज़्यादा खराब है, यह मुझे ठीक से समझ नहीं आ रहा
हम services बनाते हैं और ऐसे patterns इस्तेमाल करते हैं जिन्हें web interface या CLI जैसे सभी consumers use करते हैं, और इन चीज़ों के न टूटने की बात मेरे द्वारा पहले देखी गई किसी भी approach से बड़ा improvement रही है
junior developers interfaces के बारे में नहीं सोचते—यह शिकायत tRPC ही नहीं, किसी भी API के साथ समान रूप से आने की संभावना है
Notion में tRPC जैसी API style इस्तेमाल होती रही है, और वह API tRPC से लगभग 4 साल पहले से थी
TypeScript के mapped types से ऐसी चीज़ आसानी से खुद बनाई जा सकती है। keys API names हों और values
{ request, response }type वाले object type हों, बस इतना करना हैserver side पर हर API handler को
APIs["addUser"]["request"]लेने औरPromisereturn करने वाले function के रूप में define करें, और client पर उसे उन्हीं arguments और return type वाले async function के रूप में expose करेंइस strategy को HTTPS internal API, WebSocket-based real-time API, Electron और Webview के बीच IPC, और iOS/Android native व Webview के बीच OS webview IPC में इस्तेमाल किया जाता है
native APIs में server side Swift या Kotlin में होता है, इसलिए request/response types को TypeScript में हाथ से फिर से लिखते हैं। किसी दिन इसे अपने IDL वाले binary format में बदलेंगे, लेकिन धीरे-धीरे बढ़ने वाली single cross-language API के लिए Protobuf जैसी चीज़ों की developer experience cost अभी सार्थक नहीं लगी
यह perfect नहीं है, लेकिन request/response types के साथ काफ़ी अच्छा API interface देता है
साथ ही
mockApi((request) => response)की तरह call किया जा सकने वाला 10-line mock API wrapper बनाया है, जो type-check करता है कि mock function API को सही तरह implement करता है या नहीं, और असली API function जैसा ही दिखने वाला function return करता है[0]: https://github.com/ferdikoomen/openapi-typescript-codegen
लगता है कि इस approach को अपनाने वाली अच्छी तरह maintain और promote की गई library अभी नहीं आई है, इसलिए इसकी चर्चा अक्सर नहीं होती
tRPC, JSON Schema और type generation, Zod जैसी चीज़ें इस्तेमाल करते समय असली value इसी हिस्से में होती है
call करते समय generic argument खुद देने को भी कहता है, जो dependency tree को साफ़-सुथरा रखने की कोशिश करते समय काफ़ी खराब लगता है
https://github.com/mikew/transmission-material-ui/blob/maste...
https://github.com/mikew/transmission-material-ui/blob/maste...
tRPC मुझे बहुत पसंद है। TypeScript-only stack में developer experience को चरम तक ले जाना कमाल की बात है, और इसने GraphQL community को query language की सीमाओं और trade-offs को पहचानने पर मजबूर किया
साथ ही, tRPC ने hype cycle बहुत तेजी से पार कर लिया, और ऐसा नहीं लगता कि REST और GraphQL से RPC की ओर बड़े पैमाने पर migration हो रहा है
हालांकि आजकल RPC में दिलचस्पी काफी दिखती है, और हमारे बनाए BFF framework(https://wundergraph.com/) में भी tRPC और पुराने NextJS के कुछ ideas अपनाकर file-based routing और RPC को जोड़ा गया है
tRPC के अलावा, हर operation के लिए JSON Schema अपने-आप generate करते हैं, और पूरे operations set के लिए OpenAPI spec भी generate करते हैं
RPC endpoints के bundle को OpenAPI spec या Postman collection के रूप में आसानी से share किया जा सकता है, इसलिए लोगों को यह approach पसंद आती है। HTTP verbs पर चर्चा भी लगभग नहीं होती, और practical तौर पर सिर्फ queries, mutations और subscriptions ही होते हैं
जानना चाहूंगा कि आजकल लोग GraphQL, REST, RPC style APIs का इस्तेमाल कैसे कर रहे हैं, और API में कितने लोग या कितनी teams शामिल होती हैं
REST API side पर ts-rest(https://ts-rest.com), zodios(https://www.zodios.org), Hono(https://hono.dev) हैं
अगर team में कई languages इस्तेमाल होती हैं, तो Fern भी है: https://www.buildwithfern.com
हम federated schema बदलने पर हर बार GraphQL types generate करते हैं, और file save करते समय हर बार queries और mutations के response types generate करते हैं
endpoint consumer generation library से इन्हें आसानी से abstract भी किया जा सकता है, लेकिन इसके अलावा सामान्य web API की तुलना में वास्तव में क्या ज्यादा मिलता है, समझ नहीं आता
आखिरकार हर backend call में जो काम करना है, वह वैसे ही करना पड़ता है
tRPC पसंद है। अब तक देखे गए full-stack developer experience में यह साफ तौर पर सबसे अच्छा है, और खासकर Zod के साथ इस्तेमाल करने पर API सचमुच शानदार बनती है
Zod और tRPC को मैं TypeScript के भविष्य के अहम projects मानता हूं, और लगता है कि अगले कुछ वर्षों में TypeScript ecosystem में tRPC से प्रेरित developer experience बड़े पैमाने पर खिलेगा
जिन projects में tRPC का DNA पहले से साफ दिखता है, उनमें अलग use case को target करने वाला Ping का UploadThing(https://github.com/pingdotgg/uploadthing) और हमारा Lusat(https://github.com/lusatai/lusat) शामिल हैं
ऊपर से validation errors का type इस पर निर्भर करता है कि कौन-सा schema जांचा जा रहा है, यह भी परेशान करने वाला है। error handling unpredictable हो जाती है और edge cases हमेशा बहुत ज्यादा होते हैं
improvement की काफी गुंजाइश है
unit tests लिखना भी काफी आसान हो गया
बड़ा problem type-safe CRUD और data migration लगता है; Mongoose का नाम बहुत लिया जाता है, लेकिन type safety के मामले में यह Zod/TypeScript से काफी पीछे हटने जैसा महसूस होता है
अभी थोड़ा बढ़ा-चढ़ाकर कहने का मन है, लेकिन कुछ programming styles में codebase में Zod जोड़ना उतना ही बड़ा फायदा दे सकता है जितना TypeScript जोड़ना
schema से शुरू करके typed services बनाने का pattern functional programming की तरफ झुकाव रखने वालों को अच्छा suit करता है
उत्सुक हूं कि tRPC version differences और migrations को कैसे handle करता है
fields का lifecycle होता है। जब वे पहली बार introduce होते हैं, तो कोई client या server उस field को नहीं जानता
clients और servers एक साथ restart नहीं होते, और उनके पास types का एक ही version भी नहीं होता
data एक version के type से लिखा जाता है और दूसरे version के type से पढ़ा जाता है
अगर guarantee कर सकते हैं कि सभी binaries, चल रहे programs और data upgrade हो जाएंगे और persistent data नहीं है, तो शायद problem न हो
लेकिन जैसे ही कई organizations शामिल होती हैं, यह guarantee करना मुश्किल हो जाता है कि सभी apps और servers latest library version से sync होंगे, फिर build होंगे और redeploy होंगे
static type checking मानती है कि version differences नहीं हैं। binary के अंदर का सारा code types define करने वाली library के एक ही version से build किया गया closed world होता है
Zod unknown fields allow कर सकता है, फिर आप उसे optional field में बदल सकते हैं, और situation stable होने पर required field बना सकते हैं
बेशक, जिन लोगों को tRPC से मिलने वाली सुविधा सबसे ज्यादा चाहिए, वही इस तरह की problems के बारे में सोचने की सबसे कम संभावना रखते हैं
अगर target सिर्फ एक language है, तो schema या code generation की जरूरत न होना स्वाभाविक है
tRPC को लगभग 50 हजार lines वाले दो web applications में इस्तेमाल किया और बहुत पसंद आया। developer experience शानदार है
हालांकि tRPC का hype phase काफी पहले गुजर चुका है, और लगता है RSC का hype तेजी से उसके ऊपर आ गया
आजकल tRPC जैसा stable और अच्छा solution होने के बावजूद सब बस यही बात करते हैं कि RSC इस्तेमाल करना है या नहीं
मैं RSC के खिलाफ नहीं हूं, लेकिन discussion बहुत ज्यादा है। आजकल application बनाते समय tRPC बहुत practical तरीका है
जोड़ा गया: RSC का मतलब React Server Components है, और यह read/write data की अपनी philosophy भी साथ लाता है
ऐसे acronyms जिन्हें लोग न जानते हों, उन्हें define कर देना या link जोड़ देना अच्छा होगा
कुछ निजी projects में tRPC और Next.js इस्तेमाल किया था, और अनुभव अच्छा रहा
खासकर Create T3 App(https://create.t3.gg/) जैसे पहले से configured templates के साथ इस्तेमाल करें, तो iteration speed को मात देना मुश्किल है
साथ काम करने वाले एक developer ने tRPC की खूब तारीफ़ की, उससे पहले मुझे इसके बारे में पता नहीं था; जानने के बाद यह बहुत साफ़ तौर पर अच्छा लगा
हमने साथ में एक T3 app(tRPC, Next.js, Tailwind, TypeScript, Prisma) बनाया था, अगर देखना चाहें तो यहाँ है: https://github.com/stytchauth/stytch-t3-example
TypeScript में काम करते समय type-safe API वाकई बहुत मददगार होती है