nodejs實現restful API

小王子發表於2019-02-16

更新:
最新的原始碼和使用說明放到了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

相關文章