এক্সপ্রেস: আলাদা ফাইল থেকে রুটে অ্যাপ-ইনস্ট্যান্স কীভাবে পাস করবেন?


103

আমি আমার রুটগুলি বিভিন্ন ফাইলে বিভক্ত করতে চাই, যেখানে একটি ফাইলে সমস্ত রুট এবং অন্যটিতে সংশ্লিষ্ট ক্রিয়া রয়েছে। এটি অর্জনের জন্য আমার কাছে বর্তমানে একটি সমাধান রয়েছে, তবে ক্রিয়াকলাপে এটি অ্যাক্সেস করতে সক্ষম হওয়ার জন্য অ্যাপ-ইনস্ট্যান্টটিকে বিশ্বব্যাপী করা দরকার। আমার বর্তমান সেটআপটি এমন দেখাচ্ছে:

app.js:

var express   = require('express');
var app       = express.createServer();
var routes    = require('./routes');

var controllers = require('./controllers');
routes.setup(app, controllers);

app.listen(3000, function() {
  console.log('Application is listening on port 3000');
});

routes.js:

exports.setup = function(app, controllers) {

  app.get('/', controllers.index);
  app.get('/posts', controllers.posts.index);
  app.get('/posts/:post', controllers.posts.show);
  // etc.

};

কন্ট্রোলার / index.js:

exports.posts = require('./posts');

exports.index = function(req, res) {
  // code
};

কন্ট্রোলার / posts.js:

exports.index = function(req, res) {
  // code
};

exports.show = function(req, res) {
  // code
};

যাইহোক, এই সেটআপটির একটি বড় সমস্যা রয়েছে: আমার কাছে একটি ডাটাবেস আছে- এবং একটি অ্যাপ-দৃষ্টান্ত আমার ক্রিয়াকলাপগুলিতে পাস করতে হবে (নিয়ন্ত্রক / *। জেএস)। আমি ভাবতে পারি একমাত্র বিকল্প, উভয় ভেরিয়েবলকে বিশ্বব্যাপী করে তুলছে যা সত্যই কোনও সমাধান নয়। আমি ক্রিয়াগুলি থেকে রুটগুলি পৃথক করতে চাই কারণ আমার প্রচুর রুট রয়েছে এবং সেগুলি একটি কেন্দ্রীয় জায়গায় চাই।

ক্রিয়ায় ভেরিয়েবলগুলি পাস করার সর্বোত্তম উপায় কী তবে রুটগুলি থেকে ক্রিয়াগুলি আলাদা করুন?


আপনার কন্ট্রোলার.জেগুলি দেখতে কেমন? হতে পারে আপনি এটিকে কোনও ফাংশন করতে পারেন (কোনও বস্তুর পরিবর্তে) যা পরামিতিগুলি গ্রহণ করতে পারে।
মিহাই

প্রয়োজন ('নিয়ন্ত্রণকারী') প্রয়োজন নিয়ামক / সূচক.জেএস। যাইহোক, কোনও ফাংশন কাজ করবে না কারণ আমি রুটগুলিতে অবজেক্টটি ব্যবহার করি (রুট.জেএস দেখুন) এবং সুতরাং এটি কোনও ফাংশন হলেও এটিতে যুক্তিগুলি পাস করতে পারে না।
ক্লাদিও আলবার্টিন

উত্তর:


165

ব্যবহার req.app,req.app.get('somekey')

কলিংয়ের মাধ্যমে তৈরি করা অ্যাপ্লিকেশন ভেরিয়েবলটি express()অনুরোধ এবং প্রতিক্রিয়া অবজেক্টগুলিতে সেট করা থাকে।

দেখুন: https://github.com/visionmedia/express/blob/76147c78a15904d4e4e469095a29d1bec9775ab6/lib/express.js#L34-L35


ধন্যবাদ। আমি মনে করি এটি অ্যাপ.সেট ('নাম', ভাল) এর সাথে সেট ভেরিয়েবল অ্যাক্সেসের সেরা উপায়;
পাভেল কোস্টেনকো

4
app.set('somekey', {})অ্যাপ.জেজে কল করতে ভুলবেন না
ankitjaininfo

3
যদিও আমি এটি পছন্দ করি তবে আমার একমাত্র গ্রিপ হ'ল আপনি যখন কোনও অ্যাপ.লোকালস.অনেকর্ডাইজড (মেইন.জেএস তে নেই) চালানোর চেষ্টা করছেন তখন app.route('/something').get(app.locals.authorized,function(req,res,next){});এটি সম্ভব নয় কারণ এটি রেকর্ডের বাইরে নয়।
গ্যাবিও

আমি বিভিন্ন ক্যোয়ারী প্যারামিটারের জন্য বিভিন্ন পাসপোর্ট কৌশল ব্যবহার করছি। তাই আমি মাঝারি পাতায় পাসপোর্ট.উস ("কৌশল-নাম") সেট করার চেষ্টা করছি। এমনকি আমি যদি সেই মিডওয়্যারের মধ্যে পাসপোর্ট কেবল পাসপোর্ট = রেইক.এপ দিয়ে রাখি, ('পাসপোর্ট') পেতে পারি। এটি অন্য একটি অনুরোধের জন্য সংশোধন করা হচ্ছে। এটা এমন কেন ?
কার্তিকেয় মিশ্র

যদি আমি এটি করি, তবে আমার কাছে req অবজেক্টের রেডিস এবং ডিবি এর মতো অতিরিক্ত অবজেক্ট উদাহরণ থাকবে। এটি অ্যাপ্লিকেশন কর্মক্ষমতা প্রভাবিত করবে না? যেমন: index.js app.set ('redis', redis_client) এ; রুটস / উদাহরণ.js রাউটারে = প্রয়োজন ('এক্সপ্রেস') Rou রাউটার (); রুট.জেট ('/ পরীক্ষা', (req, res, next) => os conosle.log (req.app.get ('redis')); রিটার্ন রেজ.সেন্ড ("// সম্পন্ন");})
সুজ অান শ্রেষ্ঠ

101

নোড.জেএস বিজ্ঞপ্তি নির্ভরতা সমর্থন করে।
প্রয়োজনীয় ('./ রুটস') (অ্যাপ) পরিবর্তে বিজ্ঞপ্তি নির্ভরতা ব্যবহার করা প্রচুর কোড সাফ করে এবং প্রতিটি মডিউলকে তার লোডিং ফাইলে কম স্বনির্ভর করে তোলে:


app.js

var app = module.exports = express(); //now app.js can be required to bring app into any file

//some app/middleware setup, etc, including 
app.use(app.router);

require('./routes'); //module.exports must be defined before this line


যাত্রাপথ / index.js

var app = require('../app');

app.get('/', function(req, res, next) {
  res.render('index');
});

//require in some other route files...each of which requires app independently
require('./user');
require('./blog');


----- 04/2014 আপডেট -----
এক্সপ্রেস 4.0 একটি এক্সপ্রেস.রোটার () পদ্ধতি যুক্ত করে রুটগুলি নির্ধারণের জন্য ইউজকেসকে স্থির করেছে!
ডকুমেন্টেশন - http://expressjs.com/4x/api.html#router

তাদের নতুন জেনারেটরের উদাহরণ:
রুটটি লেখার জন্য:
https://github.com/expressjs/generator/blob/master/templates/js/routes/index.js
এটিকে অ্যাপে যুক্ত করা / নাম স্পেস করা: https://github.com /expressjs/generator/blob/master/templates/js/app.js#L24

অন্যান্য সংস্থান থেকে অ্যাপ্লিকেশন অ্যাক্সেসের জন্য এখনও ইউসকেস রয়েছে, তাই বিজ্ঞপ্তি নির্ভরতা এখনও একটি বৈধ সমাধান।


1
"এটি লোড করা ফাইলের উপর কম পারস্পরিক নির্ভরশীল" - এটি তার লোডিং ফাইলের নির্দিষ্ট ফাইলপথের উপর নির্ভর করে । এটি খুব আঁটসাঁট মিলন, সুতরাং আসুন এটি না এমন ভান করুন।
ক্যামিলো মার্টিন

2
কেবল খুব সতর্ক থাকুন (পড়ুন: আমি গত এক ঘন্টা ধরে যা করছি তার সাথে এমনটা করবেন না +) যা আপনার অ্যাপটি রফতানির পরেapp.js রাউটিং ফাইলের প্রয়োজন । বিজ্ঞপ্তি কলগুলি একটি বাস্তব জগাখিচুড়ি করতে পারে, সুতরাং তারা কীভাবে কাজ করে তা আপনি নিশ্চিত হন ! require()
নাতেওয়ামি

আমি সত্যই বলেছি যে @Feng এর কাছ থেকে রিক.এপ.জেট ('সামকি') ব্যবহারের উত্তরটি সার্কুলার নির্ভরতা ব্যবহারের চেয়ে আরও ভাল উপায় এবং পরিষ্কার সমাধান solution
ক্লোদিও মেজাসালমা

@ গ্রীন যদি অ্যাপটি খালি থাকে, আপনার প্রয়োজন এমন একটি ফাইলের দরকার যা appঅ্যাপ্লিকেশনটির আগে module.exportsসংজ্ঞায়িত করা উচিত। আপনাকে ইনস্ট্যান্টিয়েট করতে হবে app, সেট করতে হবে module.exports, তারপরে ফাইলগুলির প্রয়োজন হতে পারে যা প্রয়োজন হতে পারে app তবে যে কোনও উপায়েই , বিজ্ঞপ্তি নির্ভরতাটি একটি বিরোধী-নিদর্শন যা সমাধান করেছে - আপনার আর এটি করার দরকার নেই।
উইল স্টার

26

আমি মন্তব্যগুলিতে বলেছি, আপনি মডিউল.এপোর্টপোর্ট হিসাবে কোনও ফাংশন ব্যবহার করতে পারেন। একটি ফাংশনও একটি বস্তু, তাই আপনাকে আপনার সিনট্যাক্সটি পরিবর্তন করতে হবে না।

app.js

var controllers = require('./controllers')({app: app});

controllers.js

module.exports = function(params)
{
    return require('controllers/index')(params);
}

কন্ট্রোলার / index.js

function controllers(params)
{
  var app = params.app;

  controllers.posts = require('./posts');

  controllers.index = function(req, res) {
    // code
  };
}

module.exports = controllers;

ফাংশনের অভ্যন্তরে কোনও জিনিস ফেরত দেওয়া কি ঠিক আছে বা আপনার উদাহরণের মধ্যে পদ্ধতিগুলি সেট করা ভাল?
ক্লোদিও আলবার্টিন

আমি মনে করি উভয় পদ্ধতির ঠিক আছে।
মিহাই

যেহেতু আমার প্রচুর পদ্ধতি রয়েছে, তাই আমি এগুলি প্রতিটি ম্যানুয়ালি পরিবর্তে একটি বস্তু হিসাবে সেট করতে পছন্দ করব। আমি যখন অবজেক্টটি ফিরিয়ে দেব তখন এটি কাজ করবে, তবে কী কোনও সমাধান নেই যা একটু চাটুকার? আমার আসল পদ্ধতিগুলি দু'বার যুক্ত করা হবে ...
ক্লোদিও আলবার্টিন

যদি নিশ্চিত না আমি তোমাদের বোঝা, কিন্তু আমি অনুমান তুমি বাস্তবায়ন বাহিরে সরাতে পারে যে controllersফাংশন, ভালো কিছু: jsfiddle.net/mihaifm/yV79K
Mihai

কন্ট্রোলার / সূচক.জেসগুলি কি নিয়ন্ত্রকদের ভের ফেরানোর দরকার পড়ে না?
ইয়ালম্বার

5

বা কেবল এটি করুন:

var app = req.app

মিডলওয়্যারের ভিতরে আপনি এই রুটগুলি ব্যবহার করছেন। সে রকমই:

router.use( (req,res,next) => {
    app = req.app;
    next();
});

কেউ আমাকে বলবেন কেন এটি গৃহীত উত্তর নয়? @Feng দ্বারা উল্লিখিত হিসাবে app.use('my-service', serviceInstance)প্রধান রাউটার এবং req.app.get('my-service')নিয়ামক হিসাবে আপনি নির্ভরতার জন্য ব্যবহার করেন
ফিলিপ

0

ধরা যাক যে আপনার কাছে "কনটোলার" নামে একটি ফোল্ডার রয়েছে।

আপনার অ্যাপ.জেজে আপনি এই কোডটি রাখতে পারেন:

console.log("Loading controllers....");
var controllers = {};

var controllers_path = process.cwd() + '/controllers'

fs.readdirSync(controllers_path).forEach(function (file) {
    if (file.indexOf('.js') != -1) {
        controllers[file.split('.')[0]] = require(controllers_path + '/' + file)
    }
});

console.log("Controllers loaded..............[ok]");

... এবং ...

router.get('/ping', controllers.ping.pinging);

আপনার কন্ট্রোলারদের ফোল্ডারে আপনার এই কোড সহ "ping.js" ফাইলটি থাকবে:

exports.pinging = function(req, res, next){
    console.log("ping ...");
}

আর এটাই ....


0
  1. আপনার ডিবি অবজেক্টটি যে কোনও জায়গায় না পেরে সমস্ত কন্ট্রোলারের কাছে অ্যাক্সেসযোগ্য করে তুলতে: একটি অ্যাপ্লিকেশন-স্তরের মিডলওয়্যার তৈরি করুন যা ডিবি অবজেক্টকে প্রতিটি রেকর্ড অবজেক্টের সাথে সংযুক্ত করে, তারপরে আপনি প্রতিটি কন্ট্রোলারের মধ্যে এটি অ্যাক্সেস করতে পারবেন।
// app.js
let db = ...;  // your db object initialized
const contextMiddleware = (req, res, next) => {
  req.db=db;
  next();
};
app.use(contextMiddleware);
  1. পরিবর্তে অ্যাপ্লিকেশন উদাহরণটি যেকোন জায়গায় যেতে এড়াতে, পরিবর্তে অ্যাপ্লিকেশনটি যেখানে রয়েছে সেখানে যেতে হবে
// routes.js  It's just a mapping.
exports.routes = [
  ['/', controllers.index],
  ['/posts', controllers.posts.index],
  ['/posts/:post', controllers.posts.show]
];

// app.js
var { routes }    = require('./routes');
routes.forEach(route => app.get(...route));
// You can customize this according to your own needs, like adding post request

চূড়ান্ত অ্যাপ্লিকেশন

// app.js
var express   = require('express');
var app       = express.createServer();

let db = ...;  // your db object initialized
const contextMiddleware = (req, res, next) => {
  req.db=db;
  next();
};
app.use(contextMiddleware);

var { routes }    = require('./routes');
routes.forEach(route => app.get(...route));

app.listen(3000, function() {
  console.log('Application is listening on port 3000');
});

অন্য সংস্করণ: আপনি পোস্ট অনুরোধ যুক্ত করার মতো আপনার নিজের প্রয়োজন অনুযায়ী এটি কাস্টমাইজ করতে পারেন

// routes.js  It's just a mapping.
let get = ({path, callback}) => ({app})=>{
  app.get(path, callback);
}
let post = ({path, callback}) => ({app})=>{
  app.post(path, callback);
}
let someFn = ({path, callback}) => ({app})=>{
  // ...custom logic
  app.get(path, callback);
}
exports.routes = [
  get({path: '/', callback: controllers.index}),
  post({path: '/posts', callback: controllers.posts.index}),
  someFn({path: '/posts/:post', callback: controllers.posts.show}),
];

// app.js
var { routes }    = require('./routes');
routes.forEach(route => route({app}));

-1

ডাটাবেসের জন্য পৃথক করে ডেটা অ্যাক্সেস পরিষেবা যা সাধারণ ডিপিআই দিয়ে সমস্ত ডিবি কাজ করবে এবং ভাগ করে নেওয়া স্থিতি এড়াবে।

রুটগুলি আলাদা করা setসেটআপ ওভারহেডের মতো দেখাচ্ছে। আমি পরিবর্তে একটি কনফিগারেশন ভিত্তিক রাউটিং স্থাপন করতে পছন্দ করব। .Json বা টীকা সহ রুটগুলি কনফিগার করুন।


ডেটা অ্যাক্সেস পরিষেবাটির অর্থ কী? দেখতে কেমন লাগবে?
ক্লাদিও আলবার্টিন

আমার আসল রুটস.জেএস ফাইলটি অনেক বড় এবং এক্সপ্রেস-নেমস্পেস মডিউলটি ব্যবহার করে। আপনি কীভাবে ক্রিয়াগুলি থেকে রুটগুলি আলাদা করবেন?
ক্লাদিও আলবার্টিন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.