TypeScript में GraphQL बनाम REST: दिग्गजों का मुकाबला या कार्य के अनुसार चयन?
\n\nजब आप TypeScript में लिखते हैं, तो बैकएंड आर्किटेक्चर का सवाल बहुत महत्वपूर्ण हो जाता है। आप सिर्फ "काम करने" के लिए नहीं चाहते, बल्कि चाहते हैं कि टाइप्स उड़ें, कंपाइलेशन के दौरान त्रुटियाँ पकड़ी जाएँ, और कोड पूर्वानुमानित हो। और यहाँ डेवलपर के सामने शाश्वत विकल्प आता है: समय-परीक्षित REST या आधुनिक, लचीला GraphQL? दोनों तकनीकें TypeScript के साथ अच्छी तरह से काम करती हैं, लेकिन प्रत्येक अपनी विकास शैली निर्धारित करती है।
\n\nइस लेख में हम पानी नहीं फैलाएँगे और सामान्य सत्य नहीं बताएँगे। हम विशिष्ट उदाहरणों, कोड, कमजोर बिंदुओं और परिदृश्यों के साथ TypeScript में GraphQL बनाम REST का विश्लेषण करेंगे, जहाँ एक दृष्टिकोण दूसरे को पीछे छोड़ देता है। चलिए शुरू करते हैं!
\n\nREST: एक पुराना दोस्त जो निराश नहीं करता
\n\nREST (Representational State Transfer) एक आर्किटेक्चरल शैली है, जहाँ प्रत्येक संसाधन (उपयोगकर्ता, पोस्ट, टिप्पणी) का अपना URL होता है। आप /api/users/1 पर हिट करते हैं और उपयोगकर्ता प्राप्त करते हैं। सरल और पूर्वानुमानित। TypeScript प्रोजेक्ट्स में REST को अक्सर Express, Fastify या NestJS के माध्यम से लागू किया जाता है।
TypeScript के साथ REST में टाइपिंग
\nREST का मुख्य दर्द बैकएंड और फ्रंटएंड के बीच कमजोर संबंध है। आप JSON भेजते हैं, और फ्रंटएंड अनुमान लगाता है: "क्या आया?"। TypeScript सामान्य टाइप्स या OpenAPI (Swagger) के माध्यम से बचाता है।
\n\nउदाहरण: TypeScript के साथ Express पर बैकएंड
\n\nimport express, { Request, Response } from 'express';\n\ninterface User {\n id: number;\n name: string;\n email: string;\n}\n\nconst app = express();\napp.get('/api/users/:id', (req: Request, res: Response) => {\n const user: User = { id: +req.params.id, name: 'Alice', email: 'alice@example.com' };\n res.json(user);\n});\n\n\nफ्रंटएंड (fetch):
\n\ninterface User {\n id: number;\n name: string;\n email: string;\n}\n\nasync function getUser(id: number): Promise<User> {\n const res = await fetch(`/api/users/${id}`);\n return res.json() as Promise<User>;\n}\n\n\nसमस्या: यदि बैकएंड User की संरचना बदलता है, तो फ्रंटएंड को इसके बारे में केवल रनटाइम पर पता चलेगा। फ्रंट पर टाइप्स सिर्फ एक कॉपी हैं। समाधान: OpenAPI विनिर्देश से टाइप्स जनरेट करना।
\n\nTypeScript में REST के लाभ
\n- \n
- कैशिंग की सरलता: HTTP-कैश (CDN, ब्राउज़र) बॉक्स से बाहर काम करता है। \n
- स्पष्ट संरचना: URL = संसाधन, विधियाँ = क्रियाएँ (GET, POST, PUT, DELETE)। \n
- व्यापक समर्थन: कोई भी क्लाइंट (ब्राउज़र, curl, Postman) REST को समझता है। \n
- कम प्रवेश सीमा: यहाँ तक कि एक जूनियर भी एक घंटे में समझ जाएगा। \n
REST के नुकसान
\n- \n
- Over-fetching और Under-fetching: आप या तो अनावश्यक फ़ील्ड खींचते हैं, या कई अनुरोध करते हैं। \n
- कठोर संरचना: उपयोगकर्ता + उसके पोस्ट प्राप्त करने के लिए, दो अनुरोध या क्रच (expand फ़ील्ड) की आवश्यकता होती है। \n
- कमजोर टाइपिंग: OpenAPI के बिना, क्लाइंट पर टाइप्स सिर्फ "ईमानदार शब्द" हैं। \n
GraphQL: लचीलापन और नियंत्रण
\n\nGraphQL एक क्वेरी भाषा है जो क्लाइंट को स्वयं यह तय करने का अधिकार देती है कि कौन सा डेटा प्राप्त करना है। एक एंडपॉइंट (/graphql), एक अनुरोध - और आपको वही मिलता है जो आपने ऑर्डर किया था। TypeScript और GraphQL एक आदर्श जोड़ी हैं: टाइप्स स्वचालित रूप से स्कीमा से जनरेट होते हैं।
TypeScript के साथ GraphQL में टाइपिंग
\nपहले स्कीमा (SDL) लिखी जाती है:
\n\ntype User {\n id: ID!\n name: String!\n email: String!\n posts: [Post!]!\n}\n\ntype Post {\n id: ID!\n title: String!\n content: String!\n}\n\ntype Query {\n user(id: ID!): User\n}\n\n\nफिर टाइप्स जनरेट किए जाते हैं (graphql-codegen के माध्यम से):
// generated.ts\nexport type User = {\n __typename?: 'User';\n id: string;\n name: string;\n email: string;\n posts: Array<Post>;\n};\n\nexport type Post = {\n __typename?: 'Post';\n id: string;\n title: string;\n content: string;\n};\n