将快速路由分解为单独的文件

kl0*_*l02 4 javascript node.js express

我已经尝试了我在 s/o 上找到的所有答案,我确定我一定遗漏了一些东西。什么对我没有错误而是给了我一个 404。我尝试了来自Node.js 中组织路由的答案,strongloop 的路由分离模式,来自如何在 Express 中的多个文件中包含路由处理程序的答案?, 遇到类似Router.use 需要中间件功能的错误?但这些答案都没有奏效。在 Express 4.0中无法将路由拆分为单独的文件的答案不会出错,但也会出现 404。似乎每个答案都有不同的语法和风格,也许是我混合和匹配不正确?

现在我的 /routes/persons.js 有这个模式:

    var express = require('express');
    var persons = express.Router();

    persons.route('/persons/:user_id')
        .put(function (req, res, next) {
            // etc
    });

    module.exports = persons;       
Run Code Online (Sandbox Code Playgroud)

在我的 server.js 文件中,我有:

    var persons = require('./routes/persons');
    app.use('/persons', persons);
Run Code Online (Sandbox Code Playgroud)

这种组合不会引发错误,但也不会执行任何操作。我尝试将端点添加到 server.js 行:

    var persons = require('./routes/persons');
    app.get('/persons/:user_id', persons.addpersons);
Run Code Online (Sandbox Code Playgroud)

并将 people.js 剥离为仅导出功能:

    exports.addpersons = function (req, res, next) {
            var list = req.body;
            // etc
    }
Run Code Online (Sandbox Code Playgroud)

加样包裹在整个person.js文件的变化module.exports = function(),粘着module.exports = router在端部,使用app代替router等

我在看什么?我应该添加一些其他中间件,重新安排我调用端点的方式,使用应用程序,还是坚持使用 router.route?当没有错误但端点仍然是 404 时,最有可能的罪魁祸首是什么?

提前谢谢了!

============== 编辑包括 SERVER.JS ==============

由于很明显设置错误,因此在某处,这是我的 server.js 文件:

        var express = require('express');
        var app = express();
        var methodOverride = require('method-override');
        var mongoose = require('mongoose');
        var bodyParser = require('body-parser');
        var router = express.Router();
        var jwt    = require('jsonwebtoken');
        var config = require('./config');
        var nodemailer = require('nodemailer');
        var bcrypt = require('bcrypt-nodejs');
        var crypto = require('crypto');
        var async = require('async');

        var transporter = nodemailer.createTransport({
            service: 'gmail',
            auth: {
                user: 'email@gmail.com',
                pass: 'password'
            }
        });

        // I don't know if both are necessary, used multiple conflicting tutorials
        app.use(require('express-session')({
            secret: 'secret',
            resave: false,
            saveUninitialized: false
        }));
        app.set('superSecret', config.secret);

        var Schema = mongoose.Schema,
            Person = require('./models/person.js'),
            User = require('./models/user.js'),
            Event = require('./models/event.js');

        var port = process.env.PORT || 8080;
        mongoose.connect(config.database);

        app.use(bodyParser.json());
        app.use(bodyParser.json({ type: 'application/vnd.api+json' }));
        app.use(bodyParser.urlencoded({ extended: true }));
        app.use(methodOverride('X-HTTP-Method-Override'));
        app.use(express.static(__dirname + '/public'));

        // routes go here

        app.use('/api', router);
        app.listen(port);
        console.log('gogogo port ' + port);
Run Code Online (Sandbox Code Playgroud)

我不知道我还可以在哪里寻找为什么包含路由需要在通常的模式中进行这样的中断。我的配置文件?我的档案?这些是服务器上仅有的其他文件,不包括 /models 和 /routes。

小智 5

这里的关键是了解app.use()你的req对象(特别是req.path)有什么作用,app.get()和朋友有什么不同,以及 Express 如何包装path-to-regexp(它的内部路径匹配模块)来处理路由。

1)app.use(path, middleware) 挂载中间件。在挂载的中间件/路由器内部,req.path是相对于挂载路径的。只有请求路径的开头需要匹配,因此/foo适用于/foo(相对路径将为/)、/foo/bar(相对路径为/bar)等处的请求。

app.use(function (req, res, next) {
    console.log('Main: %s %s', req.method, req.path);
    next();
});

app.use('/foo', function (req, res) {
    console.log('In /foo: %s %s', req.method, req.path);
    res.send('Got there');
});
Run Code Online (Sandbox Code Playgroud)

尝试运行上面的设置,导航到localhost/foo并查看以下日志:

Main: GET /foo
In /foo: GET /
Run Code Online (Sandbox Code Playgroud)

2) app.get(path, middleware),app.post(path, middleware)等做不安装目标中间件,因此req.path被保留。req.path必须与您定义路由的整个模式匹配,因此/foo仅适用于/foo请求。

app.use(function (req, res, next) {
    console.log('Main: %s %s', req.method, req.path);
    next();
});

app.get('/foo', function (req, res) {
    console.log('In /foo: %s %s', req.method, req.path);
    res.send('Got there');
});
Run Code Online (Sandbox Code Playgroud)

导航到localhost/foo并查看:

Main: GET /foo
In /foo: GET /foo
Run Code Online (Sandbox Code Playgroud)

3) app.route(path),如在快速文档说明的那样,仅仅是为了方便定义多个app.get(middleware),app.post(middleware)等等共享相同path。


现在在你的情况下,这是一个工作设置:

主要的

var persons = require('./routes/persons');
app.use('/persons', persons);
Run Code Online (Sandbox Code Playgroud)

路线/persons.js

var router = require('express').Router();
router.route('/:user_id')
  .post(function (req, res) {
    // handle potato data
  })
  .get(function (req, res) {
    // get and send potato data
  });

module.exports = router;
Run Code Online (Sandbox Code Playgroud)

这很方便,因为您只需/persons在主文件中设置一次入口点,因此您可以在需要时轻松更新它(您也可以从配置文件、路由器对象或其他任何东西导入该路径值,Node 是在这方面相当灵活)。该人士路由器本身需要它的业务控制器的照顾,无论它正好安装在。