यदि आप प्लेटफ़ॉर्म नोड.जेएस के लिए विकसित कर रहे थे, तो आपने शायद
एक्सप्रेस.जेएस के बारे में सुना था। यह नोड के लिए वेब एप्लिकेशन बनाने के लिए उपयोग किए जाने वाले सबसे लोकप्रिय हल्के फ्रेमवर्क में से एक है।

सामग्री के लेखक, जिसका अनुवाद आज हम प्रकाशित करते हैं, अपने स्रोत कोड के विश्लेषण के माध्यम से एक्सप्रेस ढांचे की आंतरिक संरचना की विशेषताओं का अध्ययन करने और इसके उपयोग के एक उदाहरण पर विचार करने की पेशकश करता है। उनका मानना है कि लोकप्रिय ओपन सोर्स पुस्तकालयों में अंतर्निहित तंत्र का अध्ययन उनके बारे में गहरी समझ के लिए योगदान देता है, उनसे "रहस्य" का पर्दा हटाता है और उनके आधार पर बेहतर एप्लिकेशन बनाने में मदद करता है।
इस सामग्री को पढ़ते समय एक्सप्रेस स्रोत कोड को रखना आपको सुविधाजनक लग सकता है।
इस संस्करण का उपयोग यहां किया गया है। आप एक्सप्रेस कोड को खोले बिना इस लेख को पढ़ सकते हैं, यहाँ से, जहाँ भी उपयुक्त हो, इस पुस्तकालय के कोड टुकड़े दिए गए हैं। उन स्थानों पर जहां कोड संक्षिप्त है, प्रपत्र
// ...
की टिप्पणियों का
// ...
एक्सप्रेस का उपयोग करने का एक मूल उदाहरण
शुरुआत करने के लिए, आइए एक नज़र डालें "हैलो वर्ल्ड!" नई कंप्यूटर तकनीकों के विकास में पारंपरिक - एक उदाहरण। यह ढांचे की आधिकारिक वेबसाइट पर पाया जा सकता है, यह हमारे शोध में एक शुरुआती बिंदु के रूप में काम करेगा।
const express = require('express') const app = express() app.get('/', (req, res) => res.send('Hello World!')) app.listen(3000, () => console.log('Example app listening on port 3000!'))
यह कोड पोर्ट 3000 पर एक नया HTTP सर्वर शुरू करता है और एक
Hello World!
भेजता है
Hello World!
GET /
मार्ग पर प्राप्त अनुरोधों के लिए। यदि आप विवरण में नहीं जाते हैं, तो हम चार चरणों में अंतर कर सकते हैं कि क्या हो रहा है, जिसका हम विश्लेषण कर सकते हैं:
- एक नया एक्सप्रेस एप्लिकेशन बनाएं।
- एक नया मार्ग बनाएँ।
- निर्दिष्ट पोर्ट नंबर पर HTTP सर्वर शुरू करना।
- सर्वर के लिए आने वाले अनुरोधों को संसाधित करना।
एक नया एक्सप्रेस एप्लिकेशन बनाना
var app = express()
कमांड आपको एक नया एक्सप्रेस एप्लिकेशन बनाने की अनुमति देता है।
Lib / express.js फ़ाइल से
createApplication
फ़ंक्शन डिफ़ॉल्ट निर्यात फ़ंक्शन है; यह हम है जो
express()
फ़ंक्शन को कॉल करके इसे एक्सेस करते हैं। यहां कुछ महत्वपूर्ण बातें हैं जिन पर आपको ध्यान देना चाहिए:
// ... var mixin = require('merge-descriptors'); var proto = require('./application'); // ... function createApplication() { // , . // : `function(req, res, next)` var app = function(req, res, next) { app.handle(req, res, next); }; // ... // `mixin` `proto` `app` // - `get`, . mixin(app, proto, false); // ... return app; }
इस फ़ंक्शन से दी गई
app
ऑब्जेक्ट हमारे एप्लिकेशन कोड में उपयोग की जाने वाली वस्तुओं में से एक है।
app.get
पद्धति
app.get
मर्ज-डिस्क्रिप्टर लाइब्रेरी के
app.get
फ़ंक्शन का उपयोग करके जोड़ा
app.get
, जो
proto
में घोषित
app
विधियों को असाइन करने के लिए जिम्मेदार है।
proto
ऑब्जेक्ट स्वयं ही
lib / application.js से आयात किया जाता है।
एक नया मार्ग बनाएँ
अब आइए उस
कोड को देखें जो हमारे उदाहरण से
app.get
विधि बनाने के लिए जिम्मेदार है।
var slice = Array.prototype.slice; // ... /** * `.VERB(...)` `router.VERB(...)`. */ // `methods` HTTP, ( ['get','post',...]) methods.forEach(function(method){ // app.get app[method] = function(path){ // // var route = this._router.route(path); // route[method].apply(route, slice.call(arguments, 1)); // `app`, return this; }; });
यह ध्यान रखना दिलचस्प है कि, सिमेंटिक फीचर्स के अलावा, HTTP क्रियाओं को लागू करने वाले सभी तरीके, जैसे कि
app.get
,
app.post
,
app.put
और जैसे, कार्यक्षमता के मामले में, समान माना जा सकता है। यदि आप उपर्युक्त कोड को सरल करते हैं, तो इसे केवल एक विधि
get
करने के लिए कम करके, आपको निम्न जैसा कुछ मिलेगा:
app.get = function(path, handler){ // ... var route = this._router.route(path); route.get(handler) return this }
यद्यपि उपरोक्त फ़ंक्शन के 2 तर्क हैं, यह फ़ंक्शन
app[method] = function(path){...}
। दूसरा तर्क,
handler
,
slice.call(arguments, 1)
को कॉल करके प्राप्त किया जाता है।
संक्षेप में,
app.<method>
बस अपने
route
विधि का उपयोग करके एप्लिकेशन राउटर में मार्ग को बचाता है, और फिर
handler
को
route.<method>
।
राउटर
route()
राउटर विधि को
लिबर / राउटर / इंडेक्स में घोषित किया गया है।
// proto - `_router` proto.route = function route(path) { var route = new Route(path); var layer = new Layer(path, { sensitive: this.caseSensitive, strict: this.strict, end: true }, route.dispatch.bind(route)); layer.route = route; this.stack.push(layer); return route; };
route.get
,
lib / राउटर / मार्ग में
route.get
विधि की घोषणा
app.get
की घोषणा के
app.get
:
methods.forEach(function (method) { Route.prototype[method] = function () { // `flatten` , [1,[2,3]], var handles = flatten(slice.call(arguments)); for (var i = 0; i < handles.length; i++) { var handle = handles[i]; // ... // , , Layer, // var layer = Layer('/', {}, handle); // ... this.stack.push(layer); } return this; }; });
प्रत्येक मार्ग में कई हैंडलर हो सकते हैं, प्रत्येक हैंडलर के आधार पर, टाइप
Layer
एक चर का निर्माण किया जाता है, जो एक डाटा प्रोसेसिंग लेयर है, जो तब स्टैक पर मिलती है।
परतदार वस्तुएं
_router
और
route
दोनों प्रकार की वस्तुओं का उपयोग करते हैं। ऐसी वस्तु के सार को समझने के लिए, आइए इसके
निर्माता को देखें :
function Layer(path, options, fn) { // ... this.handle = fn; this.regexp = pathRegexp(path, this.keys = [], opts); // ... }
टाइप
Layer
ऑब्जेक्ट बनाते समय
Layer
उन्हें एक पथ, कुछ पैरामीटर और एक फंक्शन दिया जाता है। हमारे राउटर के मामले में, यह फ़ंक्शन
route.dispatch
है।
route.dispatch
(हम इसके बारे में अधिक बात करेंगे, सामान्य शब्दों में, इसे एक अलग मार्ग के लिए अनुरोध प्रेषित करने के लिए डिज़ाइन किया गया है)। मार्ग के मामले में, यह फ़ंक्शन हमारे उदाहरण के कोड में घोषित हैंडलर फ़ंक्शन है।
टाइप
Layer
प्रत्येक ऑब्जेक्ट में एक
हैंडल_रेक्वेस्ट विधि होती है, जो ऑब्जेक्ट को इनिशियलाइज़ किए जाने पर पारित फ़ंक्शन को निष्पादित करने के लिए ज़िम्मेदार होती है।
app.get
पद्धति का उपयोग करके मार्ग बनाते समय क्या होता है उसे याद करें:
- एप्लिकेशन के राउटर में एक मार्ग बनाया गया है (
this._router
)। dispatch
मार्ग विधि को संबंधित Layer
ऑब्जेक्ट के हैंडलर विधि के रूप में सौंपा गया है, और यह ऑब्जेक्ट राउटर स्टैक पर धकेल दिया जाता है।- अनुरोध हैंडलर को
Layer
ऑब्जेक्ट को हैंडलर विधि के रूप में पास किया जाता है, और इस ऑब्जेक्ट को रूट स्टैक पर धकेल दिया जाता है।
नतीजतन, सभी हैंडलर
app
उदाहरण के अंदर
Layer
टाइप की वस्तुओं के रूप में संग्रहीत किए जाते हैं जो रूट स्टैक के अंदर होते हैं, जिनके राउटर
Layer
ऑब्जेक्ट को राउटर स्टैक में दिए जाते हैं:
राउटर स्टैक और रूट स्टैक पर लेट ऑब्जेक्टइनकमिंग HTTP अनुरोध इस तर्क के अनुसार संसाधित किए जाते हैं। हम उनके बारे में नीचे बात करेंगे।
HTTP सर्वर स्टार्टअप
मार्गों को कॉन्फ़िगर करने के बाद, आपको सर्वर शुरू करने की आवश्यकता है। हमारे उदाहरण में, हम
app.listen
पद्धति की ओर
app.listen
, इसे पोर्ट नंबर और कॉलबैक फ़ंक्शन को तर्कों के रूप में पास करते हैं। इस पद्धति की विशेषताओं को समझने के लिए, हम
lib / application.js फ़ाइल का संदर्भ ले सकते हैं:
app.listen = function listen() { var server = http.createServer(this); return server.listen.apply(server, arguments); };
app.listen
आसपास सिर्फ एक आवरण है। यह दृष्टिकोण समझ में आता है, क्योंकि यदि आप याद करते हैं कि हमने बहुत शुरुआत में क्या बात की थी, तो
app
केवल एक फ़ंक्शन है जिसमें हस्ताक्षर
function(req, res, next) {...}
, जो
http.createServer
लिए आवश्यक तर्कों के साथ संगत है
http.createServer
(इस पद्धति का हस्ताक्षर
function (req, res) {...}
) है।
यह महसूस करने के बाद, अंत में, जो कुछ भी व्यक्त करता है। जेएस हमें देता है उसे एक बहुत ही बुद्धिमान फ़ंक्शन-हैंडलर में कम किया जा सकता है, रूपरेखा अब पहले की तरह जटिल और रहस्यमय नहीं लगती है।
HTTP अनुरोध प्रसंस्करण
अब जब हम जानते हैं कि
app
केवल एक अनुरोध हैंडलर है, तो हम उस पथ का अनुसरण करेंगे जो एक HTTP एप्लिकेशन एक्सप्रेस एप्लिकेशन के अंदर से गुजरता है। यह रास्ता हमारे द्वारा घोषित हैंडलर की ओर ले जाता है।
सबसे पहले, अनुरोध
createApplication
फ़ंक्शन (
lib / express.js ) पर जाता है:
var app = function(req, res, next) { app.handle(req, res, next); };
फिर यह
app.handle
मेथड (
lib / application.js ) पर जाता है:
app.handle = function handle(req, res, callback) { // `this._router` - , , `app.get` var router = this._router; // ... // `handle` router.handle(req, res, done); };
router.handle
मेथड
lib / रूटर / index.js में घोषित किया गया है:
proto.handle = function handle(req, res, out) { var self = this; //... // self.stack - , // Layer ( ) var stack = self.stack; // ... next(); function next(err) { // ... // var path = getPathname(req); // ... var layer; var match; var route; while (match !== true && idx < stack.length) { layer = stack[idx++]; match = matchLayer(layer, path); route = layer.route; // ... if (match !== true) { continue; } // ... HTTP, } // ... // process_params , self.process_params(layer, paramcalled, req, res, function (err) { // ... if (route) { // `layer.handle_request` // `next` // , `next` , // , `next` , return layer.handle_request(req, res, next); } // ... }); } };
यदि आप वर्णन करते हैं कि संक्षेप में क्या हो रहा है, तो
router.handle
फ़ंक्शन स्टैक पर सभी परतों से गुजरता है जब तक कि वह उस एक को नहीं पाता जो अनुरोध में निर्दिष्ट पथ से मेल खाता है। फिर,
handle_request
लेयर विधि को बुलाया जाएगा, जो पूर्वनिर्धारित हैंडलर फ़ंक्शन को निष्पादित करेगा। यह हैंडलर फंक्शन एक
dispatch
रूट मेथड है, जो
लिब / रूट / जो रूट में घोषित किया गया है:
Route.prototype.dispatch = function dispatch(req, res, done) { var stack = this.stack; // ... next(); function next(err) { // ... var layer = stack[idx++]; // ... layer.handle_request(req, res, next); // ... } };
जिस तरह राउटर के मामले में, प्रत्येक मार्ग के प्रसंस्करण के दौरान, इस मार्ग की परतों की गणना की जाती है और लेयर हैंडलर विधियों को अंजाम देने वाले उनके
handle_request
तरीकों को
handle_request
। हमारे मामले में, यह एक अनुरोध हैंडलर है, जिसे एप्लिकेशन कोड में घोषित किया गया है।
यहां, अंत में, HTTP अनुरोध हमारे आवेदन के कोड क्षेत्र में आता है।
एक्सप्रेस आवेदन में पथ का अनुरोध करेंपरिणाम
यहां हमने एक्सप्रेस.जेएस लाइब्रेरी के केवल मूल तंत्रों की जांच की, जो वेब सर्वर के संचालन के लिए जिम्मेदार हैं, लेकिन इस लाइब्रेरी में कई अन्य विशेषताएं भी हैं। हम हैंडलर तक पहुंचने से पहले अनुरोधों को चेक से रोकते नहीं थे, हम उन सहायक विधियों के बारे में बात नहीं करते थे जो
res
और
req
चर के साथ काम करते समय उपलब्ध होते हैं। और अंत में, हम एक्सप्रेस की सबसे शक्तिशाली विशेषताओं में से एक पर स्पर्श नहीं किया। इसमें मिडलवेयर का उपयोग होता है, जिसका उद्देश्य लगभग किसी भी समस्या को हल करने के लिए किया जा सकता है - पार्स करने के अनुरोध से लेकर एक संपूर्ण प्रमाणीकरण प्रणाली लागू करने तक।
हमें उम्मीद है कि इस सामग्री ने आपको एक्सप्रेस डिवाइस की मुख्य विशेषताओं को समझने में मदद की, और अब, यदि आवश्यक हो, तो आप इस पुस्तकालय के स्रोत कोड के कुछ हिस्सों का स्वतंत्र रूप से विश्लेषण करके बाकी सब समझ सकते हैं जो आपकी रुचि रखते हैं।
प्रिय पाठकों! क्या आप एक्सप्रेस.जेएस का उपयोग करते हैं?
