【问题标题】:How to separate routes on Node.js and Express 4?如何在 Node.js 和 Express 4 上分离路由?
【发布时间】:2014-07-18 08:52:49
【问题描述】:

我想从我的 server.js 文件中分离出路由。

我在 Scotch.io 上关注本教程 http://scotch.io/tutorials/javascript/build-a-restful-api-using-node-and-express-4

如果所有行都在 server.js 文件上,它就可以工作。但我无法分开。我怎样才能做到这一点?

server.js

// set up ======================================================================
var express = require('express');
var app = express();
var bodyParser = require('body-parser');

// configuration ===============================================================
app.use(bodyParser());

var port = process.env.PORT || 8000;

var mongoose = require('mongoose');
var database = require('./config/database');
mongoose.connect(database.url);
var Video = require('./app/models/video');

// routes =======================================================================
app.use('/api', require('./app/routes/routes').router);

// listen (start app with node server.js) ======================================
app.listen(port);
console.log("ready captain, on deck" + port);

module.exports = app;

还有 app/routes/routes.js

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

router.use(function(req, res, next) {
  console.log('Something is happening.');
  next();
});

router.get('/', function(req, res) {
  res.json({ message: 'hooray! welcome to our rest video api!' });  
});


router.route('/videos')

  .post(function(req, res) {

    var video = new Video();
    video.title = req.body.title;

    video.save(function(err) {
  if (err)
    res.send(err);

  res.json({ message: 'Video criado!' });
});


  })

  .get(function(req, res) {
    Video.find(function(err, videos) {
      if (err)
        res.send(err);

      res.json(videos);
    });
  });

module.exports.router = router;

【问题讨论】:

  • 节点错误是什么?我认为 routes.js 中的 module.exports = { router: router } 应该这样做
  • 嗨@bbuecherl,我收到ReferenceError:视频未定义
  • 您的视频似乎有小写的“v”,并试图为视频引用大写的“V”。
  • 他好像找不到Video,你需要把你的行var Video = require("./app/models/video");server.js移到routes.js
  • 在 route.js 中包含 video.js 时,请使用正确的路径,例如“..\models\video”

标签: node.js express router


【解决方案1】:

Server.js

var express = require('express');
var app = express();

app.use(express.static('public'));

//Routes
app.use(require('./routes'));  //http://127.0.0.1:8000/    http://127.0.0.1:8000/about

//app.use("/user",require('./routes'));  //http://127.0.0.1:8000/user  http://127.0.0.1:8000/user/about


var server = app.listen(8000, function () {

  var host = server.address().address
  var port = server.address().port

  console.log("Example app listening at http://%s:%s", host, port)

})

routes.js

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

//Middle ware that is specific to this router
router.use(function timeLog(req, res, next) {
  console.log('Time: ', Date.now());
  next();
});


// Define the home page route
router.get('/', function(req, res) {
  res.send('home page');
});

// Define the about route
router.get('/about', function(req, res) {
  res.send('About us');
});


module.exports = router;

*在 routs.js 中你应该定义中间件

参考http://wiki.workassis.com/nodejs-express-separate-routes/

【讨论】:

  • 完美答案。
  • 干净的答案(y)
  • 当我有更多路线时,这个答案如何扩展? @Bikesh
  • 使用这种方法时,我注意到我的 req.body 返回未定义,再次将其放入 index.js 时,body 出现了。有什么想法吗?
  • @Calvintwr 只需使用不同的路由(routes2.js 等)创建更多文件。
【解决方案2】:

就从主文件中分离路线而言..

Server.js

//include the routes file
var routes = require('./routes/route');
var users = require('./routes/users');
var someapi = require('./routes/1/someapi');

////////
app.use('/', routes);
app.use('/users', users);
app.use('/1/someapi', someapi);

routes/route.js

//last line - try this
module.exports = router;

对于新项目,您也可以在命令行上尝试

express project_name

你需要快速生成器

【讨论】:

  • 这并没有真正分离路由,它分离了控制器。 @Bikesh 有更正确的解决方案。
  • 我正在尝试将 API 从主应用程序文件中分离出来,然后显示错误 apiRoutes.post('/register', function(req, res, next) { ^ TypeError: Cannot read property 'post' of undefined at Object.<anonymous> (F:\saurabh_sharma\nodejs\salecrm\app\routes.js:4:10) at Module._compile (module.js:413:34) at Object.Module._extensions..js (module.js:422:10) ...
【解决方案3】:

另一种使用 Express 4.0 将路由分成自己的文件的方法:

server.js

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

routes.js

module.exports = (function() {
    'use strict';
    var router = require('express').Router();

    router.get('/', function(req, res) {
        res.json({'foo':'bar'});
    });

    return router;
})();

【讨论】:

  • 为什么要在函数内部使用'use strict';
  • @KarlMorrison 我想这只是为了满足 linter。
  • 将整个路由定义包装在 (function() { ... })() 构造中的好处是什么?
  • @SylvainLeroux - 节点具有文​​件级变量范围,因此我可以看到在这种情况下 IIFE 没有任何好处。应该取出来。
  • 我遇到了 app.use('/', routes) 的问题,所以我只需要使用 app.use(routes)。我所有的路线都只是点击 router.get('/')。
【解决方案4】:

一种将路由分离到自己的文件中的方法。

SERVER.JS

var routes = require('./app/routes/routes');  //module you want to include
var app=express();
routes(app);   //routes shall use Express

ROUTES.JS

module.exports=function(app) {
 //place your routes in here..
 app.post('/api/..., function(req, res) {.....}   //example
}

【讨论】:

  • 我不喜欢到处传递app。这不是一个整洁的解决方案。
【解决方案5】:

如果您将 express-4.xTypeScript 和 ES6 一起使用,这将是最好的模板;

src/api/login.ts

import express, { Router, Request, Response } from "express";

const router: Router = express.Router();
// POST /user/signin
router.post('/signin', async (req: Request, res: Response) => {
    try {
        res.send('OK');
    } catch (e) {
        res.status(500).send(e.toString());
    }
});

export default router;

src/app.ts

import express, { Request, Response } from "express";
import compression from "compression";  // compresses requests
import expressValidator from "express-validator";
import bodyParser from "body-parser";
import login from './api/login';

const app = express();

app.use(compression());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(expressValidator());

app.get('/public/hc', (req: Request, res: Response) => {
  res.send('OK');
});

app.use('/user', login);

app.listen(8080, () => {
    console.log("Press CTRL-C to stop\n");
});

使用varmodule.exports 更清晰可靠。

【讨论】:

    【解决方案6】:

    我遇到的一个问题是在使用 router.use 时尝试使用方法记录路径。使用最终使用此方法来解决它。允许您将路径保留到较高级别的较低路由器级别。

    routes.js

    var express = require('express');
    var router = express.Router();
    
    var posts = require('./posts');
    
    router.use(posts('/posts'));  
    
    module.exports = router;
    

    posts.js

    var express = require('express');
    var router = express.Router();
    
    let routeBuilder = path => {
    
      router.get(`${path}`, (req, res) => {
        res.send(`${path} is the path to posts`);
      });
    
      return router
    
    }
    
    module.exports = routeBuilder;
    

    如果您记录路由器堆栈,您实际上可以看到路径和方法

    【讨论】:

      【解决方案7】:

      我们应该只需要 2 行代码

      TL;DR

      $ npm install express-routemagic --save
      
      const magic = require('express-routemagic')
      magic.use(app, __dirname, '[your route directory]')
      

      就是这样!

      更多信息:

      你会怎么做呢?让我们从文件结构开始:

      project_folder
      |--- routes
      |     |--- api
      |           |--- videos
      |           |     |--- index.js
      |           |
      |           |--- index.js
      |     
      |--- server.js
      

      请注意,在路线下有一个结构。 Route Magic 是文件夹感知的,并且会自动暗示这是您的 api uri 结构。

      在 server.js 中

      只需两行代码:

      const magic = require('express-routemagic')
      magic.use(app, __dirname, 'routes')
      

      在路由/api/index.js中

      const router = require('express').Router()
      
      router.get('/', (req, res) => { 
          res.json({ message: 'hooray! welcome to our rest video api!' })
      })
      

      在 routes/api/videos/index.js 中

      Route Magic 知道您的文件夹结构并为您的 api 设置相同的结构,因此此 url 将是 api/videos

      const router = require('express').Router()
      
      router.post('/', (req, res) => { /* post the video */ })
      router.get('/', (req, res) => { /* get the video */ })
      

      免责声明:我写了这个包。不过真的是姗姗来迟,等人来写已经到了我的极限了。

      【讨论】:

        【解决方案8】:

        就我而言,我希望尽可能多地使用 Typescript。以下是我使用课程组织路线的方式:

        export default class AuthService {
            constructor() {
            }
        
            public login(): RequestHandler {
               return this.loginUserFunc;
            }
        
            private loginUserFunc(req: Request, res: Response): void {
                User.findOne({ email: req.body.email }, (err: any, user: IUser) => {
                    if (err)
                        throw err;
                    if(!user)
                        return res.status(403).send(AuthService.noSuccessObject());
                    else
                        return AuthService.comparePassword(user, req, res);
                })
            }
        }
        

        从您的 server.js 或您拥有服务器代码的地方,您可以通过以下方式调用 AuthService:

        import * as express from "express";
        import AuthService from "./backend/services/AuthService";
        
        export default class ServerApp {
            private authService: AuthService;
        
            this.authService = new AuthService();
        
            this.myExpressServer.post("/api/login", this.authService.login(), (req: express.Request, res: express.Response) => {
            });
        }
        

        【讨论】:

          猜你喜欢
          • 2021-09-29
          • 1970-01-01
          • 2014-10-17
          • 2020-07-23
          • 2016-09-20
          • 1970-01-01
          • 1970-01-01
          • 2015-12-10
          • 2015-01-17
          相关资源
          最近更新 更多