GraphQL क्या है?
November 4, 2022
GraphQL क्या है? यह कितना लोकप्रिय है?
GraphQL एक API-उन्मुख क्वेरी मैनिपुलेशन भाषा है जिसे 2015 में Facebook द्वारा जारी किया गया था। अन्य API डिज़ाइनों के विपरीत, GraphQL क्लाइंट्स को पूर्व-सहमत डेटा संरचना के आधार पर क्वेरी स्टेटमेंट बनाने की अनुमति देता है और सर्वर को स्टेटमेंट को पार्स करके केवल आवश्यक डेटा वापस करने की सुविधा प्रदान करता है। इस तरह, GraphQL समृद्धि और लचीलापन प्रदान करता है जबकि अतिरिक्त डेटा के कारण होने वाले प्रदर्शन हानि से बचता है, जो GraphQL को उन एप्लिकेशन्स के लिए एक बेहतरीन विकल्प बनाता है जिन्हें कई जटिल डेटा ऑब्जेक्ट्स के साथ काम करने की आवश्यकता होती है।
2018 में, GraphQL ने एक पूर्ण स्पेसिफिकेशन और एक स्थिर संस्करण जारी किया। उसी वर्ष, Facebook ने GraphQL प्रोजेक्ट को Linux Foundation के तहत GraphQL Foundation को दान कर दिया। तब से, GraphQL कई ओपन-सोर्स प्रोजेक्ट्स और वाणिज्यिक संगठनों में शामिल हो गया है। अब तक, बाजार में GraphQL के कई प्रमुख क्लाइंट-साइड इम्प्लीमेंटेशन्स उपलब्ध हैं। सर्वर-साइड इम्प्लीमेंटेशन्स सभी प्रमुख सर्वर-साइड प्रोग्रामिंग भाषाओं में उपलब्ध हैं, और यहां तक कि D और R जैसी विशेष भाषाओं में भी।
GraphQL के लिए कुछ वास्तविक परिदृश्य और चुनौतियां
GraphQL का सबसे प्रसिद्ध उदाहरण GitHub का GraphQL API है।
GraphQL को अपनाने से पहले, GitHub ने लाखों होस्टेड प्रोजेक्ट्स द्वारा उत्पन्न समृद्ध डेटा को एक्सपोज़ करने के लिए एक REST API प्रदान किया था, जो इतना सफल रहा कि यह REST APIs डिज़ाइन करते समय लोगों के लिए एक मॉडल बन गया। हालांकि, जैसे-जैसे डेटा ऑब्जेक्ट्स की संख्या बढ़ी और ऑब्जेक्ट्स के भीतर फील्ड्स बड़े होते गए, REST API में अधिक से अधिक कमियां सामने आने लगीं। सर्वर साइड पर, GitHub को प्रत्येक कॉल के साथ उत्पन्न डेटा की मात्रा के कारण लागत को कम करने के लिए कॉल की आवृत्ति पर सख्त सीमाएं निर्धारित करनी पड़ीं। डेवलपर साइड पर, उन्हें इस सीमा का सामना करना पड़ा क्योंकि एकल कॉल बहुत सारा डेटा वापस करता है, लेकिन उसका अधिकांश भाग बेकार होता है। किसी विशेष जानकारी को प्राप्त करने के लिए, डेवलपर्स को अक्सर कई क्वेरीज़ लॉन्च करनी पड़ती हैं और फिर क्वेरी परिणामों से सार्थक डेटा को एक साथ जोड़कर वांछित सामग्री बनाने के लिए बहुत सारा ग्लू कोड लिखना पड़ता है। इस प्रक्रिया में, उन्हें "कॉल की संख्या" की बेड़ियां भी पहननी पड़ती हैं।
इसलिए, Github ने GraphQL को जैसे ही जारी किया गया, इसे अपना लिया। GitHub GraphQL का "राजदूत" बन गया, जिसने इसके एप्लिकेशन को हजारों डेवलपर्स तक पहुंचाया। GraphQL API अब Github के लिए शीर्ष विकल्प है। GraphQL के समर्थन की पहली घोषणा के बाद से, GitHub ने हर साल GraphQL के बारे में कई लेख पोस्ट किए हैं। डेवलपर्स को GraphQL में माइग्रेट करने में सक्षम बनाने के लिए, GitHub ने इस उद्देश्य के लिए विशेष रूप से एक इंटरैक्टिव क्वेरी एप्लिकेशन लिखा है: https://docs.github.com/en/graphql/overview/explorer। डेवलपर्स इस एप्लिकेशन के माध्यम से GraphQL लिखना सीख सकते हैं।
हालांकि, GraphQL कोई रामबाण नहीं है। हाल ही में, GitHub ने अपने पैकेज API के GraphQL इम्प्लीमेंटेशन को डिप्रेकेट कर दिया। कई लोगों ने GraphQL की कुछ कमियों पर चर्चा शुरू कर दी है। GraphQL की कई समस्याएं इस तथ्य से उत्पन्न होती हैं कि इसकी संरचना HTTP मानक से इतनी अलग है कि GraphQL के कुछ अवधारणाओं को HTTP पथ/हेडर जैसी संरचना में मैप करने का कोई आसान तरीका नहीं है। GraphQL को एक सामान्य HTTP API के रूप में मानने के लिए अतिरिक्त विकास कार्य की आवश्यकता होती है। परिणामस्वरूप, जो डेवलपर्स अपने स्वयं के GraphQL APIs को प्रबंधित करना चाहते हैं, उन्हें GraphQL-सक्षम API गेटवे का उपयोग करना होगा।
APISIX कैसे GraphQL का समर्थन करता है
वर्तमान में, APISIX GraphQLs के कुछ गुणों के माध्यम से डायनामिक रूटिंग का समर्थन करता है। इस क्षमता के साथ, हम केवल विशिष्ट GraphQL अनुरोधों को स्वीकार कर सकते हैं या अलग-अलग GraphQLs को अलग-अलग अपस्ट्रीम्स पर फॉरवर्ड कर सकते हैं।
निम्नलिखित GraphQL स्टेटमेंट को एक उदाहरण के रूप में लें:
query getRepo { owner { name } repo { created } }
APISIX GraphQL के निम्नलिखित तीन गुणों को रूटिंग के लिए निकालता है:
- graphql_operation
- graphql_name
- graphql_root_fields
उपरोक्त GraphQL स्टेटमेंट में:
graphql_operationqueryसे मेल खाता हैgraphql_namegetRepoसे मेल खाता हैgraphql_root_fields["owner", "repo"]से मेल खाता है
आइए APISIX की GraphQL के लिए सूक्ष्म रूटिंग क्षमताओं को प्रदर्शित करने के लिए एक रूट बनाएं:
curl http://127.0.0.1:9180/apisix/admin/routes/1 \ -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -i -d ' { "methods": ["POST"], "uri": "/graphql", "vars": [ ["graphql_operation", "==", "query"], ["graphql_name", "==", "getRepo"], ["graphql_root_fields", "has", "owner"] ], "upstream": { "type": "roundrobin", "nodes": { "127.0.0.1:2022": 1 } } }'
अगला, एक GraphQL स्टेटमेंट के साथ एक अनुरोध का उपयोग करके एक्सेस करें:
curl -i -H 'content-type: application/graphql' \ -X POST http://127.0.0.1:9080/graphql -d ' query getRepo { owner { name } repo { created } }' HTTP/1.1 200 OK ...
हम देख सकते हैं कि अनुरोध अपस्ट्रीम तक पहुंच गया क्योंकि क्वेरी स्टेटमेंट सभी तीन शर्तों से मेल खाता है।
इसके विपरीत, यदि हम एक मिसमैच स्टेटमेंट के साथ एक्सेस करते हैं, उदाहरण के लिए, owner फील्ड शामिल नहीं है:
curl -i -H 'content-type: application/graphql' \ -X POST http://127.0.0.1:9080/graphql -d ' query getRepo { repo { created } }' HTTP/1.1 404 Not Found ...
यह संबंधित रूटिंग नियम से मेल नहीं खाएगा।
हम अतिरिक्त रूप से एक रूट बना सकते हैं जो owner फील्ड शामिल नहीं करने वाले स्टेटमेंट्स को किसी अन्य अपस्ट्रीम पर रूट करने की अनुमति देता है:
curl http://127.0.0.1:9180/apisix/admin/routes/2 \ -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -i -d ' { "methods": ["POST"], "uri": "/graphql", "vars": [ ["graphql_operation", "==", "query"], ["graphql_name", "==", "getRepo"], ["graphql_root_fields", "!", "has", "owner"] ], "upstream": { "type": "roundrobin", "nodes": { "192.168.0.1:2022": 1 } } }'
curl -i -H 'content-type: application/graphql' \ -X POST http://127.0.0.1:9080/graphql -d ' query getRepo { repo { created } }' HTTP/1.1 200 OK ...
APISIX के भविष्य में GraphQL समर्थन की संभावनाएं
डायनामिक रूटिंग के अलावा, APISIX भविष्य में GraphQL के विशिष्ट फील्ड्स के आधार पर अधिक ऑपरेशन्स शुरू कर सकता है। उदाहरण के लिए, GitHub के GraphQL API में रेट लिमिटिंग के लिए एक विशिष्ट फॉर्मूला है, और हम समान नियमों को लागू करके एक एकल GraphQL अनुरोध को संबंधित संख्या में "वर्चुअल कॉल्स" में परिवर्तित कर सकते हैं ताकि GraphQL-विशिष्ट रेट लिमिटिंग को पूरा किया जा सके।
हम इस समस्या को एक अलग तरीके से भी सोच सकते हैं। एप्लिकेशन स्वयं अभी भी REST API प्रदान करता है, और गेटवे सबसे बाहरी स्तर पर GraphQL अनुरोधों को REST अनुरोधों में और REST प्रतिक्रियाओं को GraphQL प्रतिक्रियाओं में परिवर्तित करता है। इस तरह प्रदान किया गया GraphQL API RBAC, रेट लिमिटिंग, कैशिंग आदि जैसे कार्यों को विशेष प्लगइन्स विकसित किए बिना कर सकता है। तकनीकी दृष्टिकोण से, इस विचार को लागू करना इतना कठिन नहीं है। आखिरकार, 2022 में, यहां तक कि REST APIs भी OpenAPI स्पेक्स को स्कीमा के रूप में प्रदान करते हैं, जो GraphQL स्कीमा और OpenAPI स्कीमा के बीच एक स्थानांतरण है, साथ ही GraphQL-विशिष्ट फील्ड फ़िल्टरिंग है। (बेशक, मुझे यह स्वीकार करना चाहिए कि मैंने इसे स्वयं अभ्यास नहीं किया है। हो सकता है कि कुछ विवरणों में चुनौतियां हों जिन्हें अभी तक दूर नहीं किया गया है।)
सावधान पाठक यह पाएंगे कि इस तरह परिवर्तित किए गए GraphQL APIs एक समय में केवल एक मॉडल पर काम कर सकते हैं, जो स्पष्ट रूप से GraphQL की लचीलापन आवश्यकताओं को पूरा नहीं करता है और GraphQL के कपड़े पहने एक REST API से ज्यादा कुछ नहीं है। हालांकि, GraphQL में एक अवधारणा है जिसे स्कीमा स्टिचिंग कहा जाता है जो इम्प्लीमेंटर्स को कई स्कीमास को एक साथ जोड़ने की अनुमति देता है।
एक उदाहरण के रूप में, हमारे पास दो APIs हैं, एक GetEvent और दूसरा GetLocation, जो क्रमशः Event और Location प्रकार वापस करते हैं।
type Event { id: string location_id: string } type Location { id: string city: string } type Query { GetEvent(id: string): Event GetLocation(id: string): Location }
हम एक कॉन्फ़िगरेशन जोड़ सकते हैं जो इन दो APIs को एक नए API में जोड़ता है जिसे GetEventWithLocation कहा जाता है, जो इस तरह दिखता है:
type EventWithLocation { id: string location: Location } type Query { GetEventWithLocation(id: string): EventWithLocation }
स्टिचिंग का विशिष्ट कार्यान्वयन गेटवे द्वारा पूरा किया जाता है। उपरोक्त उदाहरण में, गेटवे API को दो भागों में विभाजित करता है, GetEvent को location_id प्राप्त करने के लिए कॉल करता है और फिर GetLocation को संयुक्त डेटा प्राप्त करने के लिए कॉल करता है।
संक्षेप में, REST को GraphQL में परिवर्तित करके, प्रत्येक REST API को संबंधित GraphQL मॉडल में बदला जा सकता है; और स्कीमा स्टिचिंग की मदद से, कई मॉडल्स को एक GraphQL API में जोड़ा जा सकता है। इस तरह, हम मौजूदा REST API के ऊपर एक समृद्ध और लचीला GraphQL API बना सकते हैं और REST API की ग्रैन्युलैरिटी पर विशिष्ट प्लगइनs को प्रबंधित कर सकते हैं। यह डिज़ाइन संयोग से कुछ API ऑर्केस्ट्रेशन समस्याओं को हल करता है। जैसा कि उपरोक्त उदाहरण में, हम एक API (Event.location_id) के आउटपुट को दूसरे API (Location.id) के इनपुट के रूप में लेते हैं।