Protobuf IDL से सेवाएँ और संदेश परिभाषित करना
.proto अनुबंध लिखिए और उनसे टाइप-सुरक्षित क्लाइंट व सर्वर स्टब बनाइए।
Protobuf IDL से सेवाएँ और संदेश परिभाषित करना, CoddyKit पर Node.js बैकएंड विकास बूटकैंप का एक निःशुल्क पाठ है। यह 4 में से 1वाँ पाठ है। आप नीचे पूरा पाठ निःशुल्क पढ़ सकते हैं—फिर अंतर्निहित कोड संपादक और 24/7 एआई ट्यूटर के साथ ब्राउज़र में इसका व्यावहारिक अभ्यास कर सकते हैं। यह Node.js बैकएंड विकास बूटकैंप सीखने के मार्ग का हिस्सा है और आपकी प्रगति वेब तथा CoddyKit ऐप पर सिंक होती रहती है। Node.js बैकएंड विकास बूटकैंप पाठ्यक्रम में कुल 4 पाठ शामिल हैं।
IDL क्यों?
gRPC माइक्रोसर्विस में कॉन्ट्रैक्ट कोड से पहले आता है। आप अपने डेटा और RPC मेथड को भाषा-निरपेक्ष इंटरफ़ेस परिभाषा भाषा (IDL) में लिखते हैं, जिसे .proto कहा जाता है, और फिर उसी एक फ़ाइल से Node.js, Go, Java आदि के लिए टाइप-सुरक्षित स्टब जनरेट करते हैं।
- एक
.protoफ़ाइल क्लाइंट और सर्वर द्वारा साझा किया गया सत्य का एकमात्र स्रोत होती है। - Protocol Buffers (protobuf) IDL और बाइनरी वायर फ़ॉर्मैट, दोनों है।
- आपको सीरियलाइज़ेशन कोड हाथ से लिखने की आवश्यकता नहीं होती — कंपाइलर यह काम करता है।
इस पाठ में बताया गया है कि .proto कॉन्ट्रैक्ट कैसे लिखें और उन्हें JavaScript क्लाइंट व सर्वर स्टब में कैसे बदलें।
.proto फ़ाइल की संरचना
हर आधुनिक .proto फ़ाइल की शुरुआत सिंटैक्स संस्करण और पैकेज घोषित करने से होती है। package आपके प्रतीकों के लिए नेमस्पेस बनाता है, ताकि दो सेवाएँ बिना टकराव के User परिभाषित कर सकें।
syntax = "proto3";— नई सेवाओं के लिए हमेशा proto3 का उपयोग करें।package— तार्किक नेमस्पेस, जो जनरेशन के बाद JS ऑब्जेक्ट पथ में बदल जाता है।- फ़ाइल में
message(डेटा संरचनाएँ) औरservice(RPC मेथड) को समूहित किया जाता है।
// user.proto
syntax = "proto3";
package users.v1;
// A data shape sent over the wire
message User {
string id = 1;
string email = 2;
bool active = 3;
}मैसेज और फ़ील्ड नंबर
message टाइप वाले फ़ील्ड का रिकॉर्ड होता है। = के बाद की संख्या फ़ील्ड टैग होती है, डिफ़ॉल्ट मान नहीं। बाइनरी वायर पर protobuf हर फ़ील्ड की पहचान टैग से करता है — एक मैसेज के भीतर ये अद्वितीय होने चाहिए और डिप्लॉय होने के बाद इन्हें कभी नहीं बदलना चाहिए।
- फ़ील्ड के नाम स्वतंत्र रूप से बदले जा सकते हैं; बैकवर्ड संगतता के लिए टैग स्थिर रहने चाहिए।
- 1-15 टैग एक बाइट का उपयोग करते हैं, इसलिए इन्हें सबसे अधिक उपयोग होने वाले फ़ील्ड के लिए सुरक्षित रखें।
- स्केलर प्रकार:
string,bool,int32,int64,double,bytes।
message Product {
string id = 1; // tag 1 (1 byte on the wire)
string name = 2;
int32 stock = 3;
double price = 4;
bool discontinued = 5;
}proto3 से JavaScript प्रकारों का मैपिंग
जब आप @grpc/proto-loader से .proto लोड करते हैं, तो हर protobuf प्रकार एक JavaScript मान में मैप हो जाता है। इस मैपिंग को जानने से रनटाइम पर होने वाले आश्चर्यों से बचा जा सकता है।
string,bool,int32,float,double, JS केstring,boolean,numberमें मैप होते हैं।int64/uint64JS में डिफ़ॉल्ट रूप से string में मैप होते हैं (संख्याएँNumber.MAX_SAFE_INTEGERसे बड़ी हो सकती हैं)।bytesएकBufferबन जाता है।- अनसेट proto3 स्केलर अपने शून्य मान (
"",0,false) के रूप में वापस आते हैं — वायर पर वे कभीundefinedनहीं होते।
// What a decoded User object looks like in Node.js
const user = {
id: 'u_123', // string -> string
email: '', // unset string -> '' (zero value)
active: false, // unset bool -> false
loginCount: '0' // int64 -> string, not number!
};
console.log(typeof user.loginCount); // 'string'सेवा परिभाषित करना
service ब्लॉक उन RPC मेथड की सूची देता है जिन्हें क्लाइंट कॉल कर सकते हैं। हर rpc ठीक एक अनुरोध मैसेज लेता है और ठीक एक प्रतिक्रिया मैसेज लौटाता है। अनुरोध और प्रतिक्रिया को समर्पित मैसेज में लपेटने से (सीधे स्केलर भेजने के बजाय) कॉन्ट्रैक्ट तोड़े बिना बाद में फ़ील्ड जोड़ना संभव होता है।
- परंपरा के अनुसार मेथड के नाम
PascalCaseमें होते हैं। - हर मेथड के लिए हमेशा एक अनुरोध और एक प्रतिक्रिया मैसेज परिभाषित करें, भले ही उनमें से कोई एक खाली हो।
message GetUserRequest { string id = 1; }
message GetUserResponse { User user = 1; }
service UserService {
// unary: one request -> one response
rpc GetUser(GetUserRequest) returns (GetUserResponse);
rpc CreateUser(CreateUserRequest) returns (User);
}RPC के चार प्रकार
rpc घोषणा के किसी भी ओर मौजूद stream कीवर्ड स्ट्रीमिंग मॉडल को नियंत्रित करता है। यही IDL कीवर्ड तय करता है कि आपके जनरेट किए गए हैंडलर को एक मान मिलेगा या स्ट्रीम।
- यूनरी:
rpc Get(Req) returns (Res)— एक इनपुट, एक आउटपुट। - सर्वर स्ट्रीमिंग:
returns (stream Res)— सर्वर कई मान भेजता है। - क्लाइंट स्ट्रीमिंग:
(stream Req)— क्लाइंट कई मान अपलोड करता है। - द्विदिशात्मक:
(stream Req) returns (stream Res)।
service OrderService {
rpc GetOrder(GetOrderRequest) returns (Order);
rpc ListOrders(ListOrdersRequest) returns (stream Order);
rpc ImportOrders(stream Order) returns (ImportSummary);
rpc LiveOrders(stream OrderEvent) returns (stream OrderEvent);
}एनम, repeated और नेस्टेड मैसेज
स्केलर के अलावा protobuf वास्तविक दुनिया के डेटा के लिए मिश्रित संरचनाएँ भी देता है।
enum— मानों का सीमित सेट; पहला सदस्य अनिवार्य रूप से0होना चाहिए और वही डिफ़ॉल्ट होता है।repeated— क्रमबद्ध सूची; यह JSArrayमें डिकोड होती है।- नेस्टेड मैसेज संरचित उप-रिकॉर्ड का मॉडल बनाते हैं।
नामों के टकराव से बचने के लिए एनम सदस्यों के आगे उपसर्ग लगाएँ, क्योंकि एनम मान बाहरी स्कोप साझा करते हैं।
enum OrderStatus {
ORDER_STATUS_UNSPECIFIED = 0; // required zero default
ORDER_STATUS_PENDING = 1;
ORDER_STATUS_SHIPPED = 2;
}
message Order {
string id = 1;
OrderStatus status = 2;
repeated LineItem items = 3; // -> JS Array
}
message LineItem {
string sku = 1;
int32 qty = 2;
}Node.js में कॉन्ट्रैक्ट लोड करना
Node में आप @grpc/proto-loader और @grpc/grpc-js की सहायता से रनटाइम पर स्टब जनरेट करते हैं। लोडर .proto को पार्स करता है और loadPackageDefinition उसे आपके पैकेज पथ के आधार पर नेविगेट किए जा सकने वाले JS ऑब्जेक्ट में बदल देता है।
keepCase: trueफ़ील्ड के नामों को proto में लिखे गए रूप में ही रखता है।longs: String64-बिट इंटिजर को स्ट्रिंग के रूप में सुरक्षित रखता है।- पैकेज पथ
users.v1,proto.users.v1बन जाता है।
const protoLoader = require('@grpc/proto-loader');
const grpc = require('@grpc/grpc-js');
const pkgDef = protoLoader.loadSync('user.proto', {
keepCase: true,
longs: String,
enums: String,
defaults: true,
oneofs: true,
});
const proto = grpc.loadPackageDefinition(pkgDef);
const UserService = proto.users.v1.UserService;सर्वर स्टब लागू करना
जनरेट किया गया UserService आपको एक सेवा परिभाषा देता है, जिसके साथ आप हैंडलर पंजीकृत करते हैं। हर यूनरी हैंडलर को (call, callback) मिलता है; call.request आपका डिकोड किया हुआ अनुरोध मैसेज होता है और आप Node-शैली के callback(err, response) से उत्तर देते हैं।
grpc.statusसे प्राप्तcodeवाली त्रुटि पास करके gRPC स्थिति लौटाएँ।- प्रतिक्रिया ऑब्जेक्ट के फ़ील्ड प्रतिक्रिया मैसेज के फ़ील्ड से मेल खाने चाहिए।
const server = new grpc.Server();
server.addService(UserService.service, {
GetUser(call, callback) {
const { id } = call.request;
const user = db.find(id);
if (!user) {
return callback({
code: grpc.status.NOT_FOUND,
message: `User ${id} not found`,
});
}
callback(null, { user });
},
});क्लाइंट स्टब से कॉल करना
वही जनरेट किया गया UserService क्लाइंट कंस्ट्रक्टर भी होता है। आप इसे लक्ष्य पते और क्रेडेंशियल के साथ इंस्टैंशिएट करते हैं, फिर मेथड को सीधे कॉल करते हैं। हर यूनरी कॉल में अनुरोध ऑब्जेक्ट और Node-शैली का कॉलबैक लिया जाता है।
- स्थानीय/डेवलपमेंट के लिए
credentials.createInsecure()का उपयोग करें; प्रोडक्शन में TLS इस्तेमाल करें। - अनुरोध और प्रतिक्रिया proto मैसेज से मेल खाने वाले साधारण JS ऑब्जेक्ट होते हैं।
const client = new UserService(
'localhost:50051',
grpc.credentials.createInsecure()
);
client.GetUser({ id: 'u_123' }, (err, res) => {
if (err) {
console.error(err.code, err.message);
return;
}
console.log(res.user.email);
});कॉन्ट्रैक्ट को सुरक्षित रूप से विकसित करना
कॉन्ट्रैक्ट तभी उपयोगी है जब डिप्लॉय किए गए क्लाइंट को तोड़े बिना उसमें बदलाव किया जा सके। कुछ नियमों का पालन करने पर proto3 में जोड़-आधारित विकास सुरक्षित रहता है।
- जोड़ें नए फ़ील्ड, जिनके लिए पहले कभी उपयोग न किए गए नए टैग नंबर हों — पुराने क्लाइंट उन्हें अनदेखा कर देते हैं।
- टैग को कभी दोबारा उपयोग या पुनः क्रमांकित न करें; हटाए गए टैग को
reservedसे चिह्नित करें। - फ़ील्ड का नाम बदलना वायर-संगत होता है (महत्वपूर्ण टैग होता है), लेकिन JSON/टेक्स्ट उपयोग को तोड़ देता है।
- टैग नंबर और नाम, दोनों के लिए
reservedका उपयोग करें, ताकि उनका आकस्मिक पुनः उपयोग न हो।
message User {
reserved 4, 5; // retired tags, never reuse
reserved "phone"; // retired field name
string id = 1;
string email = 2;
bool active = 3;
string display_name = 6; // safe additive change
}त्वरित जाँच
आपको डिप्लॉय किए गए User मैसेज से अप्रचलित phone फ़ील्ड (टैग 4) हटाना है। इसे बैकवर्ड-संगत तरीके से हटाने का सही तरीका क्या है?
पुनरावलोकन
आपने Protobuf IDL के साथ gRPC कॉन्ट्रैक्ट डिज़ाइन करना और उनका उपयोग करना सीखा:
syntax = "proto3"औरpackageवाली.protoफ़ाइल क्लाइंट और सर्वर के लिए सत्य का एकमात्र स्रोत होती है।messageटाइप वाले रिकॉर्ड परिभाषित करता है; हर फ़ील्ड के बाद की संख्या उसका स्थिर वायर टैग होती है, डिफ़ॉल्ट मान नहीं।service+rpcमेथड घोषित करते हैं;streamकीवर्ड यूनरी, सर्वर, क्लाइंट या द्विदिशात्मक स्ट्रीमिंग चुनता है।enum,repeatedऔर नेस्टेड मैसेज अधिक समृद्ध डेटा का मॉडल बनाते हैं;int64एक JS स्ट्रिंग में डिकोड होता है।- Node में
@grpc/proto-loader+grpc.loadPackageDefinitionसर्वर सेवा और क्लाइंट कंस्ट्रक्टर, दोनों जनरेट करते हैं। - कॉन्ट्रैक्ट को जोड़-आधारित तरीके से विकसित करें और हटाए गए टैग/नाम को
reservedसे सुरक्षित रखें।
एआई शिक्षक के साथ JavaScript सीखें — निःशुल्क
अपने ब्राउज़र में वास्तविक कोड लिखें और चलाएँ, चौबीसों घंटे एआई शिक्षक से तुरंत सहायता पाएँ, और वेब या ऐप पर वहीं से शुरू करें जहाँ आपने छोड़ा था।
- पाठ्यक्रम
- 22
- पाठ
- 92
अक्सर पूछे जाने वाले प्रश्न
क्या “Protobuf IDL से सेवाएँ और संदेश परिभाषित करना” पाठ निःशुल्क है?
हाँ—“Protobuf IDL से सेवाएँ और संदेश परिभाषित करना” का पूरा पाठ यहाँ वेब पर निःशुल्क पढ़ा जा सकता है। इंटरैक्टिव अभ्यास (अंतर्निहित कोड संपादक और 24/7 एआई ट्यूटर) करने और Node.js बैकएंड विकास बूटकैंप पाठ्यक्रम का बाकी हिस्सा अनलॉक करने के लिए CoddyKit PRO लें। Node.js बैकएंड विकास बूटकैंप पाठ्यक्रम में कुल 4 पाठ शामिल हैं।
“Protobuf IDL से सेवाएँ और संदेश परिभाषित करना” में मैं क्या सीखूँगा?
.proto अनुबंध लिखिए और उनसे टाइप-सुरक्षित क्लाइंट व सर्वर स्टब बनाइए। आप ब्राउज़र में सीधे चलाए जाने वाले व्यावहारिक कोड के साथ Node.js बैकएंड विकास बूटकैंप का अभ्यास करते हैं, और पाठ पूरा करते समय 24/7 एआई ट्यूटर आपके प्रश्नों के उत्तर देता है।
क्या Node.js बैकएंड विकास बूटकैंप शुरू करने के लिए मुझे किसी अनुभव की आवश्यकता है?
पहले के अनुभव की आवश्यकता नहीं है। CoddyKit पर Node.js बैकएंड विकास बूटकैंप शुरुआती से लेकर उन्नत शिक्षार्थियों तक सभी के लिए व्यवस्थित किया गया है, इसलिए आप यहीं से या शुरुआत से सीखना शुरू कर सकते हैं और अपनी गति से आगे बढ़ सकते हैं। यह 4 में से 1वाँ पाठ है।
“Protobuf IDL से सेवाएँ और संदेश परिभाषित करना” पाठ पूरा करने में कितना समय लगता है?
CoddyKit का अधिकांश पाठ लगभग 5–10 मिनट में पूरा हो जाता है। हर पाठ छोटा और संवादात्मक है, इसलिए आप लगातार प्रगति करते हैं और वेब या ऐप पर वहीं से सीखना जारी रख सकते हैं जहाँ आपने छोड़ा था।
क्या मैं इस Node.js बैकएंड विकास बूटकैंप पाठ में कोड लिख और चला सकता हूँ?
हाँ। हर Node.js बैकएंड विकास बूटकैंप पाठ में एक अंतर्निर्मित कोड संपादक शामिल है, जिससे आप सीधे अपने ब्राउज़र में वास्तविक कोड लिख और चला सकते हैं और तुरंत एआई प्रतिक्रिया पा सकते हैं—स्थानीय सेटअप की आवश्यकता नहीं है।
इस पाठ्यक्रम के सभी पाठ
- Protobuf IDL से सेवाएँ और संदेश परिभाषित करना
- Unary, Server, Client और द्विदिश स्ट्रीमिंग RPC
- इंटरसेप्टर, समय-सीमाएँ और मेटाडेटा
- Proto का विकास और पिछली संगतता