通过Express4构建Restful API服务器 - 结合AngularJS前后端分离开发

原创
2014/11/26 16:00
阅读数 2.7K

初衷

    很久没有写Nodejs了,记得去年还很兴致勃勃的打算搞一搞,结果工作一变动大半年都扑在了项目上,玩起了AngularJS.

    最近打算做项目的架构转型,也是受了"前后端二次分离"的大浪潮的影响,看了淘宝中途岛和腾讯的一些案例,觉得Nodejs可以搞搞,所以你懂得~又开始折腾了.


犹豫

    犹豫的问题主要在于Node是否必要上?如果只是说Node是否必须上,答案肯定是否定的,不然没有Node的时候大家都不做开发了?

    不过从另一个角度上看,自从开发的职责分工逐渐细化,确实不能单纯按照浏览器和服务器区划分前端后端的职责.从这个角度上看,基于对前端友好的特性,Node确实可以胜任和前端对接这一部分.所以我们最后讨论的结果还是Node要上,因为它确实可以显而易见的解决一些前端开发的问题.

    比如现在因为前端后端完全分离,前端只需要数据接口就可以了.但是前端需要的所有数据都要和后端开发API数据接口的人协商,多次沟通以及反复沟通造成的成本,完全可以通过前端开发人使用Node解决.也就是后端编写原子性的业务接口,然后由前端自己组合成最适合页面需要的.

    当然那些都是技术原因,其实在项目组中参考意义不大.毕竟你Nodejs能实现的事情,基本上所有后端语言都可以,Nodejs的友好也只是对前端工程师而已.之前在知乎上也看过一个评价淘宝中途岛项目的高人,据说淘宝内部其实也只是一群前端工程师在自娱自乐,自己玩的很happy,还没有后端工程师的肯定和支持,更别提公司的支持了

    不过不管怎样,对于一个喜爱前端热爱JS的程序猿来说,能用一种语言书写前后端,完整的Web程序还是一个不小的诱惑,既然现在公司有条件支持我这样做,何乐而不为.


选择

    由于已经确定了前后端分离的大路线,并且在AngularJS的道路上已经玩耍了一阵.那么Nodejs这一层基本上就不需要MVC或者Full-Stack的框架了,当然期间也尝试了各种Nodejs框架比如:mean,meteor,koa,hapi,restify等等.不得不说尽管连TJ这样的主神级别大神都放弃Nodejs转投Go,但是Nodejs的发展依然远超其他语言和平台,爆发着惊人的活力.

    在众多框架中挑来挑去最后还是选择了express这个Nodejs最老牌的框架,考虑有三:

1. 完善的支持体系,stack-overflow问题数过万,文档以及资料都很齐全,可以从网上得到很好地技术支持.

2. Express4以后优化了中间件,基本都抽离出来了,并且对于路由的支持更好.

3. 因为是最早的Nodejs官网推荐框架,熟悉的人比较多,不管是组内成员学习还是新招人,都可以比较好的适应,降低项目风险.


项目构建

    把准备工作完善后就开始进入代码编写的阶段了,推荐两个极好的工具对于我这种不使用IDE的人来说尤为合适,supervisor和inspector.前者可以在你修改Nodejs代码后自动重启服务器,后者可以提供Nodejs的Chrome调试工具,很多很多赞~

  目录结构

    这些准备好之后,可以构思一下代码结构了.好的架构一定是层次清晰的,文件以及文件夹的组织结构很大程度上影响了开发的难度.    

restful-express4
  -- controllers/
  -- models/
  -- routes/
  -- .gitnore
  -- app.js
  -- LISCNSE
  -- package.json
  -- README.md

    这是一个基础的结构,可以看到没有静态资源的相关目录.这里我说明一下整个项目的大体结构和思路,前端是用AngularJS构建的完整的前端App,通过Nginx的部署将映射静态资源.其他非静态的接口请求则由Nginx转发给Nodejs,Nodejs作为restful的web服务器存在,至于Nodejs下面还有什么就可以根据底层架构决定,比如直接数据库,或者rpc服务.

    这里我就想单纯的构建restful接口服务器,所以没有静态资源.

    上面的机构稍微解释一下,应用的入口在app.js中.routes提供路由规则,controllers则是具体的路由业务处理,models提供对应的数据模型或者底层数据接口.

  代码

    具体看一下代码,首先是app.js,加了注释感觉还是很容易懂的:

// Base Setup
// ====================================================================================================
// call the package we need
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
// configure app to use middleware bodyParser()
// let us get the data from a POST
app.use(bodyParser.urlencoded({extend:true}));
app.use(bodyParser.json());
// set our port
var port = process.env.PORT || 8888;
// base route for API
// ====================================================================================================
require('./routes/users.routes.js')(app);
// start the api server
// ====================================================================================================
app.listen(port);
console.log('server start on port ' + port);

    这里app.js仅仅提供一个应用的入口,把需要的东西引入,在项目复杂之后可以考虑一些autoload的方式进行相关的引入,总之app.js的责任应该很单一,很轻,没有任何逻辑和业务.

    然后分别看一下route,controller,model中的代码,这个顺序就是代码的执行的顺序.

    users.routes.js: 

'use strict';
/**
 * Module dependencies.
 */
var usersController = require('../controllers/users.controller');
module.exports = function(app) {
  // User Routes
  app.route('/api/users')
    .get(usersController.list);
};

    users.controller.js:

'use strict';
/**
 * Module dependencies.
 */
var userModel = require('../models/user.model.js');
/**
 * List of users
 */
exports.list = function(req, res) {
  userModel.find(function(err, users) {
    if (err) {
      return res.status(400).send({
        message: 'something error'
      });
    } else {
      res.json(users);
    }
  });
};

    user.model.js:

'use strict';
var users = [
  {
    name: 'Person1',
    age: 1
  },{
    name: 'Person1',
    age: 2
  },{
    name: 'Person3',
    age: 3
  },{
    name: 'Person4',
    age: 4
  },{
    name: 'Person5',
    age: 5
  }
]
module.exports = {
  find: function(callback){
    callback(null,users);
  }
};

    代码写到这里,已经可以跑起一个基本的restful服务器了.上面这套结构是一个简单的分层,当然我个人觉得可以应对大多数web应用.复杂的web应用需要做的就是在这个基础上添加各种中间件,比如身份校验,数据过滤等等.

    github地址:https://github.com/BigKunLun/restful-express4

展开阅读全文
打赏
1
31 收藏
分享
加载中
顽Shi博主

引用来自“乐颠嘞”的评论

可以nodejs、express4、mongoose,增加登录判断、权限控制的小例子吗?

引用来自“顽Shi”的评论

类似的例子网上应该有的,思路也很简单就是通过中间件,过滤所有的请求,先验证是否登录,再验证是否有当前操作的permission.如果想要比较完整的例子,可以搜索一下mean这个项目,感觉应该有demo.

引用来自“乐颠嘞”的评论

我在网上找过类似的demo,他们的过滤器判断要么写一个filter ,然后每个路由上加filter去判断是否登录,感觉这种方式不够灵活。也找到过中间件的形式,不是因为先后顺序导致静态文件也被判断未登录导致404,或者此中间件极度简陋,和case判断一样非常的高耦合,暂为倒找一个java 或者c# 里aop形式的低耦合实现方式。
中间件的那种校验基本都是AOP风格的实现了,nodejs或者express应该有的,demo还是不少的这种.
2014/12/17 16:04
回复
举报

引用来自“乐颠嘞”的评论

可以nodejs、express4、mongoose,增加登录判断、权限控制的小例子吗?

引用来自“顽Shi”的评论

类似的例子网上应该有的,思路也很简单就是通过中间件,过滤所有的请求,先验证是否登录,再验证是否有当前操作的permission.如果想要比较完整的例子,可以搜索一下mean这个项目,感觉应该有demo.
我在网上找过类似的demo,他们的过滤器判断要么写一个filter ,然后每个路由上加filter去判断是否登录,感觉这种方式不够灵活。也找到过中间件的形式,不是因为先后顺序导致静态文件也被判断未登录导致404,或者此中间件极度简陋,和case判断一样非常的高耦合,暂为倒找一个java 或者c# 里aop形式的低耦合实现方式。
2014/12/17 15:55
回复
举报
顽Shi博主

引用来自“乐颠嘞”的评论

可以nodejs、express4、mongoose,增加登录判断、权限控制的小例子吗?
类似的例子网上应该有的,思路也很简单就是通过中间件,过滤所有的请求,先验证是否登录,再验证是否有当前操作的permission.如果想要比较完整的例子,可以搜索一下mean这个项目,感觉应该有demo.
2014/12/17 15:38
回复
举报
可以nodejs、express4、mongoose,增加登录判断、权限控制的小例子吗?
2014/12/17 15:26
回复
举报
更多评论
打赏
4 评论
31 收藏
1
分享
返回顶部
顶部