简体   繁体   English

Node.js和Express 4如何分开?

[英]How to separate routes on Node.js and Express 4?

I want to separate Routes from my server.js file.我想将路由与我的 server.js 文件分开。

I am following this tutorial on Scotch.io http://scotch.io/tutorials/javascript/build-a-restful-api-using-node-and-express-4我正在关注 Scotch.io http://scotch.io/tutorials/javascript/build-a-restful-api-using-node-and-express-4上的本教程

It is working if all lines are on server.js file.如果所有行都在 server.js 文件中,它就可以工作。 But I am failing to separate.但我无法分开。 How can I make this work?我怎样才能使这项工作?

server.js服务器.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;

And the app/routes/routes.js和 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;

Server.js服务器.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路由.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;

*In routs.js you should define Middle ware *在routs.js中你应该定义中间件

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

As far as separating routes from main file is concerned..就从主文件中分离路由而言..

Server.js服务器.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路线/route.js

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

Also for new project you can try on command line同样对于新项目,您可以在命令行上尝试

express project_name

You will need express-generator for that您将需要 express-generator

Another way to separate routes into their own files with Express 4.0:使用 Express 4.0 将路由分成自己的文件的另一种方法:

server.js服务器.js

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

routes.js路由.js

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

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

    return router;
})();

One way to separate routes into their own file.将路由分离到它们自己的文件中的一种方法。

SERVER.JS服务端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
}

An issue I was running into was attempting to log the path with the methods when using router.use ended up using this method to resolve it.我遇到的一个问题是在使用 router.use 时尝试使用这些方法记录路径,最终使用此方法来解决它。 Allows you to keep path to a lower router level at the higher level.允许您在较高级别保留到较低路由器级别的路径。

routes.js路由.js

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

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

router.use(posts('/posts'));  

module.exports = router;

posts.js帖子.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;

If you log the router stack you can actually see the paths and methods如果您记录路由器堆栈,您实际上可以看到路径和方法

If you're using express-4.x with TypeScript and ES6, this would be a best template to use;如果你在TypeScript和 ES6 中使用express-4.x ,这将是一个最好的模板;

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");
});

Much clear and reliable rather using var and module.exports .更清晰可靠,而不是使用varmodule.exports

We Ought To Only Need 2 Lines of Code我们应该只需要 2 行代码

TL;DR TL; 博士

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

That's it!就是这样!

More info:更多信息:

How you would do this?你会怎么做? Let's start with file structuring:让我们从文件结构开始:

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

Note that under routes there is a structure.请注意,在路线下有一个结构。 Route Magic is folder aware, and will imply this to be the api uri structure for you automatically. Route Magic 可以识别文件夹,并且会自动暗示这是您的 api uri 结构。

In server.js在 server.js 中

Just 2 lines of code:只需两行代码:

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

In routes/api/index.js在路由/api/index.js

const router = require('express').Router()

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

In routes/api/videos/index.js在路由/api/videos/index.js

Route Magic is aware of your folder structure and sets up the same structuring for your api, so this url will be api/videos 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 */ })

Disclaimer: I wrote the package.免责声明:我写了这个包。 But really it's long-overdue, it reached my limit to wait for someone to write it.不过真的是来晚了,等人来写已经到了极限了。

I simply delcared the files and used require in the server.js file我只是删除了文件并在 server.js 文件中使用了 require

 app.use(express.json());
 require('./app/routes/devotion.route')(app);
 require('./app/routes/user.route')(app);

In my case, I like to have as much Typescript as possible.就我而言,我喜欢尽可能多的 Typescript。 Here is how I organized my routes with classes:以下是我通过课程组织路线的方式:

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);
        })
    }
}

From your server.js or where you have your server code, you can call the AuthService in the following way:从您的 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) => {
    });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM