node.js&快递 - 全球模块&应用程序结构的最佳实践 [英] node.js & express - global modules & best practices for application structure

查看:89
本文介绍了node.js&快递 - 全球模块&应用程序结构的最佳实践的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个node.js应用程序,这是一个REST api,使用express和mongoose作为我的mongodb。我现在有CRUD端点设置,但我只是想知道两件事。


  1. 如何在这里展开路由方式,具体来说,如何在路由之间共享模块。我希望我的每一条路线进入一个新的文件,但显然只有一个数据库连接,你可以看到我已经将manoose包含在people.js的顶部。


  2. 我的people.js中是否必须写出模型的架构3次?第一个模式定义了模型,然后在createPerson和updatePerson函数中列出所有的vars。这感觉就像是在一天的时候让php / mysql CRUD回来了。对于更新功能,我已经尝试编写一个循环来循环p来自动检测要更新的字段,但是没有用。任何提示或建议都会很棒。


此外,我也喜欢对整个应用程序的任何意见,对于节点来说是新的,很难知道你在做什么的方式是最有效或最好的做法。谢谢!



app.js

  // Node Modules 
var express = require('express');
app = express();
app.port = 3000;



//路由
var people = require('./ routes / people');

/ *
var locations = require('./ routes / locations');
var menus = require('./ routes / menus');
var products = require('./ routes / products');
* /


// Node配置
app.configure(function(){
app.use(express.bodyParser());
app.use(app.router);
});



//在端口3000上启动服务器
app.listen(app.port);



/ *********
ENDPOINTS
********* /

// People
app.get('/ people',people.allPeople); //返回所有人
app.post('/ people',people.createPerson); //创建一个人
app.get('/ people /:id',people.personById); //返回人员ID
app.put('/ people /:id',people.updatePerson); //通过id
app.delete('/ people /:id',people.deletePerson)更新一个人; //通过id删除一个人

console.log('服务器启动在端口'+ app.port);

people.js

  // Database 
var mongoose = require(mongoose);
mongoose.connect('mongodb://Shans-MacBook-Pro.local/lantern/');


// Schema
var Schema = mongoose.Schema;
var Person = new Schema({
first_name:String,
last_name:String,
address:{
unit:Number,
address:String,
zipcode:String,
city:String,
region:String,
country:String
},
image:String,
job_title :String,
created_at:{type:Date,default:Date.now},
active_until:{type:Date,default:null},
hourly_wage:Number,
store_id :Number,// Inheirit store info
employee_number:Number

});
var PersonModel = mongoose.model('Person',Person);


//返回所有人
exports.allPeople = function(req,res){
return PersonModel.find(function(err,person){
if(!err){
return res.send(person);
} else {
return res.send(err);
}
}) ;
}


//创建一个人
exports.createPerson = function(req,res){
var person = new PersonModel({
first_name:req.body.first_name,
last_name:req.body.last_name,
address:{
unit:req.body.address.unit,
address:req .body.address.address,
zipcode:req.body.address.zipcode,
city:req.body.address.city,
region:req.body.address.region,
country:req.body.address.country
},
image:req.body.image,
job_title:req.body.job_title,
hourly_wage:req。 body.hourly_wage,
store_id:req.body.location,
employee_number:req.body.employee_number
});

person.save(function(err){
if(!err){
return res.send(person);
} else {
console.log(err);
return res.send(404,{error:Person was not created。});
}
});

return res.send(person);
}


//通过id返回人员
exports.personById = function(req,res){
return PersonModel.findById(req.params 。$,$($)$ {

} else {
console.log(err);
return res.send(404,{error:那个人不存在。});
}
});
}


//通过id删除一个人
exports.deletePerson = function(req,res){
return PersonModel.findById(req。 params.id,function(err,person){
return person.remove(function(err){
if(!err){
return res.send(person.id +deleted );
} else {
console.log(err);
return res.send(404,{error:Person was not deleted。});
}
});
});
}



//通过id更新一个人
exports.updatePerson = function(req,res){
return PersonModel。 findById(req.params.id,function(err,p){
if(!p){
return res.send(err)
} else {
p.first_name = req.body.first_name;
p.last_name = req.body.last_name;
p.address.unit = req.body.address.unit;
p.address.address = req .body.address.address;
p.address.zipcode = req.body.address.zipcode;
p.address.city = req.body.address.city;
p.address .region = req.body.address.region;
p.address.country = req.body.address.country;
p.image = req.body.image;
p.job_title = req.body.job_title;
p.hourly_wage = req.body.hourly_wage;
p.store_id = req.body.location;
p.employee_number = req.body.employee_number;

p.save(function(err){
if(!err){
return res.send(p);
} else {
console.log(err);
return res.send(404,{error:Person was not updated。});
}
});
}
});
}


解决方案

。不要说这是最好的,但让我解释一下。


  1. 每个模式(和模型)都在自己的文件(模块) li>
  2. 特定REST资源的每组路由都在自己的文件(模块)中。

  3. 每个路由模块只需 code>它需要的Mongoose模型(仅1)

  4. 主文件(应用程序入口点)只需需要 s所有路由模块都要注册它们。

  5. Mongo连接在根文件中,并作为参数传递给任何需要。

我的应用程序根目录下有两个子文件夹 - 路由 schemas p>

这种方法的优点是:




  • 只能编写一次模式。 / li>
  • 您不会通过每个REST资源(CRUD)的4-5个路由的路由注册来污染您的主应用程序文件

  • 只能定义数据库连接一次



这是一个特定的模式文件:



文件:/schemas/theaterSchema.js

  module.exports = function(db){
return db.model('Theater',TheaterSchema());
}

function TheaterSchema(){
var Schema = require('mongoose')。

return new Schema({
title:{type:String,required:true},
description:{type:String,required:true},
address :{type:String,required:true},
纬度:{type:Number,required:false},
longitude:{type:Number,required:false},
phone:{ type:String,required:false}
});
}

以下是特定资源的路由集合如何:



文件:/routes/theaters.js

  module.exports = function(app,options){

var mongoose = options.mongoose;
var Schema = options.mongoose.Schema;
var db = options.db;

var TheaterModel = require('../ schemas / theaterSchema')(db);

app.get('/ api / theaters',function(req,res){
var qSkip = req.query.skip;
var qTake = req.query。 take;
var qSort = req.query.sort;
var qFilter = req.query.filter;
返回TheaterModel.find()。sort(qSort).skip(qSkip).limit (qTake)
.exec(function(err,theaters){
//更多代码
});
});

app.post('/ api / theaters',function(req,res){
var theater;

theater.save(function(err){
//更多代码
});
返回res.send(影院);
});

app.get('/ api / theaters /:id',function(req,res){
return TheaterModel.findById(req.params.id,function(err, {
//更多代码
});
});

app.put('/ api / theaters /:id',function(req,res){
return TheaterModel.findById(req.params.id,function(err, {
//更多代码
});
});

app.delete('/ api / theaters /:id',function(req,res){
return TheaterModel.findById(req.params.id,function(err, {
return theater.remove(function(err){
//更多代码
});
});
});
};

这里是根应用程序文件,初始化了连接并注册了所有路由:



文件:app.js

  var application_root = __dirname,
express = require('express'),
path = require('path'),
mongoose = require('mongoose'),
http = HTTP');

var app = express();

var dbProduction = mongoose.createConnection('mongodb:// here_insert_the_mongo_connection_string');

app.configure(function(){
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(application_root,public)));
app.use('/ images / tmb',express .static(path.join(application_root,images / tmb)));
app.use('/ images / plays',express.static(path.join(application_root,images / plays)) );
app.use(express.errorHandler({dumpExceptions:true,showStack:true}));
});

app.get('/ api',function(req,res){
res.send('API is running');
});

var theatersApi = require('./ routes / theaters')(app,{'mongoose':mongoose,'db':dbProduction});
//更多代码

app.listen(4242);

希望这是有帮助的。


I'm building a node.js app that is a REST api using express and mongoose for my mongodb. I've got the CRUD endpoints all setup now, but I was just wondering two things.

  1. How do I expand on this way of routes, specifically, how do I share modules between routes. I want each of my routes to go in a new file, but obviously only one database connection as you can see i've included mongoose at the top of people.js.

  2. Do I have to write out the schema of the model 3 times in my people.js? The first schema defines the model, then I list all the vars out in the createPerson and updatePerson functions. This feels like how I made php/mysql CRUD back in the day lol. For the update function, I've tried writing a loop to loop through "p" to auto detect what fields to update, but to no avail. Any tips or suggestions would be great.

Also, I'd love any opinions on the app as a whole, being new to node, it's hard to know that the way you are doing something is the most efficient or "best" practice. Thanks!

app.js

// Node Modules
var express     = require('express');
    app         = express();
    app.port    = 3000;



// Routes
var people      = require('./routes/people');

/*
var locations   = require('./routes/locations');
var menus       = require('./routes/menus');
var products    = require('./routes/products');
*/


// Node Configure
app.configure(function(){
  app.use(express.bodyParser());
  app.use(app.router);
});



// Start the server on port 3000
app.listen(app.port);



/*********
ENDPOINTS 
*********/

// People
app.get('/people', people.allPeople); // Return all people
app.post('/people', people.createPerson); // Create A Person
app.get('/people/:id', people.personById); // Return person by id
app.put('/people/:id', people.updatePerson); // Update a person by id
app.delete('/people/:id', people.deletePerson); // Delete a person by id

console.log('Server started on port ' + app.port);

people.js

//Database
var mongoose = require("mongoose");
mongoose.connect('mongodb://Shans-MacBook-Pro.local/lantern/');


// Schema
var Schema = mongoose.Schema;  
var Person = new Schema({  
    first_name: String,
    last_name: String,
    address: {
        unit: Number,
        address: String,
        zipcode: String,
        city: String,
        region: String,
        country: String
    },
    image: String, 
    job_title: String,
    created_at: { type: Date, default: Date.now },
    active_until: { type: Date, default: null },
    hourly_wage: Number,
    store_id: Number, // Inheirit store info
    employee_number: Number

});
var PersonModel = mongoose.model('Person', Person);  


// Return all people
exports.allPeople = function(req, res){
    return PersonModel.find(function (err, person) {
      if (!err) {
        return res.send(person);
      } else {
        return res.send(err);
      }
    });
}


// Create A Person
exports.createPerson = function(req, res){
    var person = new PersonModel({
        first_name: req.body.first_name,
        last_name: req.body.last_name,
        address: {
            unit: req.body.address.unit,
            address: req.body.address.address,
            zipcode: req.body.address.zipcode,
            city: req.body.address.city,
            region: req.body.address.region,
            country: req.body.address.country
        },
        image: req.body.image,
        job_title: req.body.job_title,
        hourly_wage: req.body.hourly_wage,
        store_id: req.body.location,
        employee_number: req.body.employee_number
    });

    person.save(function (err) {
        if (!err) {
            return res.send(person);
        } else {
            console.log(err);
            return res.send(404, { error: "Person was not created." });
        }
    });

    return res.send(person);
}


// Return person by id
exports.personById = function (req, res){
  return PersonModel.findById(req.params.id, function (err, person) {
    if (!err) {
        return res.send(person);
    } else {
        console.log(err);
        return res.send(404, { error: "That person doesn't exist." });
    }
  });
}


// Delete a person by id
exports.deletePerson = function (req, res){
  return PersonModel.findById(req.params.id, function (err, person) {
    return person.remove(function (err) {
      if (!err) {
          return res.send(person.id + " deleted");
      } else {
          console.log(err);
          return res.send(404, { error: "Person was not deleted." });
      }
    });
  });
}



// Update a person by id
exports.updatePerson = function(req, res){
    return PersonModel.findById(req.params.id, function(err, p){        
        if(!p){
            return res.send(err)
        } else {
            p.first_name = req.body.first_name;
            p.last_name = req.body.last_name;
            p.address.unit = req.body.address.unit;
            p.address.address = req.body.address.address;
            p.address.zipcode = req.body.address.zipcode;
            p.address.city = req.body.address.city;
            p.address.region = req.body.address.region;
            p.address.country = req.body.address.country;
            p.image = req.body.image;
            p.job_title = req.body.job_title;
            p.hourly_wage = req.body.hourly_wage;
            p.store_id = req.body.location;
            p.employee_number = req.body.employee_number;

            p.save(function(err){
                if(!err){
                    return res.send(p);
                } else {
                    console.log(err);
                    return res.send(404, { error: "Person was not updated." });
                }
            });
        }
    });
}

解决方案

I have taken another approach here. Not saying it is the best, but let me explain.

  1. Each schema (and model) is in its own file (module)
  2. Each group of routes for a particular REST resource are in their own file (module)
  3. Each route module just requires the Mongoose model it needs (only 1)
  4. The main file (application entry point) just requires all route modules to register them.
  5. The Mongo connection is in the root file and is passed as parameter to whatever needs it.

I have two subfolders under my app root - routes and schemas.

The benefits of this approach are:

  • You only write the schema once.
  • You do not pollute your main app file with route registrations for 4-5 routes per REST resource (CRUD)
  • You only define the DB connection once

Here is how a particular schema file looks:

File: /schemas/theaterSchema.js

module.exports = function(db) {
        return db.model('Theater', TheaterSchema());
}

function TheaterSchema () {
        var Schema = require('mongoose').Schema;

        return new Schema({
            title: { type: String, required: true },
            description: { type: String, required: true },
            address: { type: String, required: true },
            latitude: { type: Number, required: false },
            longitude: { type: Number, required: false },
            phone: { type: String, required: false }
    });
}

Here is how a collection of routes for a particular resource looks:

File: /routes/theaters.js

module.exports = function (app, options) {

    var mongoose = options.mongoose;
    var Schema = options.mongoose.Schema;
    var db = options.db;

    var TheaterModel = require('../schemas/theaterSchema')(db);

    app.get('/api/theaters', function (req, res) {
            var qSkip = req.query.skip;
            var qTake = req.query.take;
            var qSort = req.query.sort;
            var qFilter = req.query.filter;
            return TheaterModel.find().sort(qSort).skip(qSkip).limit(qTake)
            .exec(function (err, theaters) {
                    // more code
            });
    });

    app.post('/api/theaters', function (req, res) {
      var theater;

      theater.save(function (err) {
        // more code
      });
      return res.send(theater);
    });

    app.get('/api/theaters/:id', function (req, res) {
      return TheaterModel.findById(req.params.id, function (err, theater) {
        // more code
      });
    });

    app.put('/api/theaters/:id', function (req, res) {
      return TheaterModel.findById(req.params.id, function (err, theater) {
        // more code
      });
    });

    app.delete('/api/theaters/:id', function (req, res) {
      return TheaterModel.findById(req.params.id, function (err, theater) {
        return theater.remove(function (err) {
          // more code
        });
      });
    });
};

And here is the root application file, which initialized the connection and registers all routes:

File: app.js

var application_root = __dirname,
        express = require('express'),
        path = require('path'),
        mongoose = require('mongoose'),
        http = require('http');

var app = express();

var dbProduction = mongoose.createConnection('mongodb://here_insert_the_mongo_connection_string');

app.configure(function () {
        app.use(express.bodyParser());
        app.use(express.methodOverride());
        app.use(app.router);
        app.use(express.static(path.join(application_root, "public")));
        app.use('/images/tmb', express.static(path.join(application_root, "images/tmb")));
        app.use('/images/plays', express.static(path.join(application_root, "images/plays")));
        app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});

app.get('/api', function (req, res) {
        res.send('API is running');
});

var theatersApi = require('./routes/theaters')(app, { 'mongoose': mongoose, 'db': dbProduction });
// more code

app.listen(4242);

Hope this was helpful.

这篇关于node.js&快递 - 全球模块&应用程序结构的最佳实践的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆