nodejs实现restful API

比特幽篁引
• 阅读 4012

更新:
最新的源码和使用说明放到了github上 点击跳转
本文的重点在于restful接口的设计与实现,使用到了express和monogoose.
点击查看express教程
点击查看monogoose教程
ES6入门教程----阮一峰的博客

node4.x对ES6的支持并不完善,建议使用更高版本的node
在实际开发中请在文件头部添加'use strict'来声明使用严格模式
为了有助于更好的理解后期的代码,我们首先来学习一下ES6的类与继承

ES6的类与继承

1.定义与使用

//定义一个基类
class BaseService{
    add(){
        console.log('base add');// base add
    }
    remove(){
        console.log('base remove') // base remove
    }
}
//实例化
var base = new BaseService();
base.add(); //输出 'base add'

2.继承

//重载基类的方法
//添加私有方法
class UserServie extends BaseService{
    add(){
    console.log('user add');// user add
    }
    findTop5(){
        console.log('1,2,3,4,5');// 1,2,3,4,5
    }
}

node的模块

其次学习一下node里的模块,如果要使用ES6的模块,你需要额外使用babel

1.导出基类
新建baseService.js

class Service{
    add(){
        console.log('base add');// base add
    }
    remove(){
        console.log('base remove') // base remove
    }
}
exports.service = Service;

2.在子类中引用基类
新建userService.js

var baseService = require('./baseService').service;
class Service extends baseService{
    findTop5(){
        console.log('1,2,3,4,5');// 1,2,3,4,5
    }
    add(){
        console.log('user add');// user add
    }
}
exports.service = Service;

搭建项目结构

下面将会使用到monogoose和express相关技术,不懂的可以看本文顶部链接
1.使用express初始化项目之后添加models文件夹和services文件夹
在models文件夹内新建userModel.js

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var model = new Schema({
     name:String
});
exports.model = mongoose.model('userModel', model);

在services文件夹内新建baseService.js

var mongoose = require('mongoose');
var Schema   = mongoose.Schema;
class Service{
    constructor(){
    }
    add(obj, name,callback){
        var name = name || '';
        var result = {};    
        var instance = this.entity(obj);
        instance.save(function(err, item, numAffected) {
            if (err) {
                result = { 'ok': false, 'data': {}, 'message': '新增' + name + '失败' }
            } else {
                result = { 'ok': true, 'data': item, 'message': '新增' + name + '成功' }
            }
            callback(result);        
        });
    }
    delete(obj, name,callback){
        var result = {};
        var id = obj.id;    
        this.entity.remove({ '_id': id }, function(err) {
            if (err) {
                result = { 'ok': false, 'data': {}, 'message': '删除' + name + '失败' };
            } else {
                result = { 'ok': true, "data": {}, 'message': '删除' + name + '成功' };
            }
            callback(result);
        });   
    }
}
exports.service = Service;

然后新建userService.js,引用对应的model,并且实现userService对baseService的继承

var baseService = require('./baseService').service;
var mongoose     = require('mongoose');
var Schema        = mongoose.Schema;
var model         = require('../models/userModel').model;
class Service extends baseService{
    constructor(){
        super();
        this.entity = model;
    }        
}
exports.service = Service;

在userService.js中我们可以重写基类的方法,也可以添加自己私有的方法和属性
在上文中已经提到过,下面再来熟悉一遍吧
如果要在子类中调用this,需要先调用super方法,否则新建实例时会报错。这是因为子类没有自己的this对象,而是继承父类的this对象,然后对其进行加工。如果不调用super方法,子类就得不到this对象。

class Service extends baseService{
    constructor(){
        super();
        this.entity = model;
    }    
    add(){
        console.log('user add');
    }
    findTop5(){
        console.log('1,2,3,4,5');
    }
}

接着再新建services.js文件来统一对外导出service ,下面代码是实际项目中的代码,仅作为参照

exports.userService               = require('./userService').service;
exports.emptyService              = require('./emptyService').service;
exports.themeService              = require('./themeService').service;
exports.documentService           = require('./documentService').service;
exports.chartTypeService          = require('./chartTypeService').service;
exports.mapTypeService            = require('./mapTypeService').service;
exports.pageService               = require('./pageService').service;
exports.cellService                = require('./cellService').service;
exports.defaultEchartTypeService = require('./defaultEchartTypeService').service;
exports.defaultMapTypeService    = require('./defaultMapTypeService').service;
exports.issueService             = require('./issueService').service;

最后是路由了,在routes文件夹内新建api.js文件

var express  = require('express');
var router   = express.Router();
var Services = require('../services/services');
mongoose.connect('mongodb://localhost/test');
/* 
    listen all
    name    名称
    method  方法
    par     参数
    entity  实体实例
    service 服务实例
    result  返回结果
    obj     请求参数
    参数为空或者错误时调用empty
    防止程序崩溃
 */
router.post('/:name?/:method?/:par?',function(req,res,next){         
    var name    = req.params.name || 'empty';      
    var method  = req.params.method || 'empty'; 
    var par     = req.params.par || '';          
    var service = new Services[name+'Service']();          
    var obj     = req.body || {};                
    obj.par     = par;                
    if(!Services[name+'Service']){
        service = new Services.emptyService();
    }            
    service[method](obj,name,function(result){        
        res.json(result);   
    });        
    return; 
});
module.exports = router;

在代码中,我们引用了Services,
首先通过new Services[name+'Service']()来实例化对应的service
然后调用service[method]方法,
其中:name?、:method?、:par? 为占位符
在前端页面中,我们可以使用$.post('/api/user/add',data,function(){})这个典型的方法来测试一下API是否可以正常运行,作者比较喜欢将参数全部放在data中
有疑问或者不解的可以发邮件到http_wenwen@163.com

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
美凌格栋栋酱 美凌格栋栋酱
6个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
1年前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
PHP创建多级树型结构
<!lang:php<?php$areaarray(array('id'1,'pid'0,'name''中国'),array('id'5,'pid'0,'name''美国'),array('id'2,'pid'1,'name''吉林'),array('id'4,'pid'2,'n
Wesley13 Wesley13
3年前
Java日期时间API系列36
  十二时辰,古代劳动人民把一昼夜划分成十二个时段,每一个时段叫一个时辰。二十四小时和十二时辰对照表:时辰时间24时制子时深夜11:00凌晨01:0023:0001:00丑时上午01:00上午03:0001:0003:00寅时上午03:00上午0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Linux日志安全分析技巧
0x00前言我正在整理一个项目,收集和汇总了一些应急响应案例(不断更新中)。GitHub地址:https://github.com/Bypass007/EmergencyResponseNotes本文主要介绍Linux日志分析的技巧,更多详细信息请访问Github地址,欢迎Star。0x01日志简介Lin
Python进阶者 Python进阶者
1年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这