前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Express.js 4,Node.js,MongoDB REST API 简易教程

Express.js 4,Node.js,MongoDB REST API 简易教程

作者头像
dys
发布2018-04-04 11:08:57
2.6K0
发布2018-04-04 11:08:57
举报
文章被收录于专栏:性能与架构性能与架构

教程内容

采用测试驱动开发的方式,开发一个简单的 REST API,包括基本的 POST/GET/PUT/DELETE 操作

先编写好针对各个接口的测试代码,包括:

  1. 调用post接口插入一个对象
  2. 调用get接口获取某个对象的数据
  3. 调用get接口获取集合数据
  4. 调用put接口更新某个对象数据
  5. 调用get接口获取更新后的对象
  6. 调用delete接口删除对象

然后针对第一个测试进行代码编写,写完后执行测试,第一个测试通过后,继续开发下一个,再进行测试,这样迭代进行

测试框架采用 Mocha,WEB框架采用 Express.js 4,数据库使用 MongoDB

前期准备

安装好 Nodejs,Mongodb,配置好npm镜像

我使用的是:nvm 安装 nodejs、Mongodb Docker 镜像、淘宝的cnpm镜像,还安装了 supervisor(检测代码变更,自动加载)

创建项目

创建一个目录 test-rest-api,然后在命令行下进入此目录

安装依赖

代码语言:javascript
复制
npm install mocha --save-dev
npm install expect.js --save-dev 
npm install superagent --save-dev
npm install express --save
npm install mongo --save
npm install mongoskin --save
npm install body-parser --save

新建代码文件

  • express.js - api 代码
  • express.test.js - 测试代码

编写测试

express.test.js 内容:

代码语言:javascript
复制
var superagent = require('superagent')
var expect = require('expect.js')
var mongoskin = require('mongoskin')
var db = mongoskin.db('mongodb://@localhost:27017/test-rest', { safe: true })

describe('express rest api server', function() {

     // 测试执行前清空数据库
    before(function() {
        db.collection('test').remove({})
    });

    var id

    // --- 测试 post 

    it('post object', function(done) {
        superagent.post('http://localhost:3000/collections/test')
            .send({
                name: 'Johns',
                email: 'john@rpjs.co'
            })
            .end(function(e, res) {
                // console.log(res.body)
                expect(e).to.eql(null)
                expect(res.body.ops.length).to.eql(1)
                expect(res.body.ops[0]._id.length).to.eql(24)
                id = res.body.ops[0]._id
                done()
            })
    })

    // --- 测试 get by ID

    it('retrieves an object', function(done) {
        superagent.get('http://localhost:3000/collections/test/' + id)
            .end(function(e, res) {
                // console.log(res.body)
                expect(e).to.eql(null)
                expect(typeof res.body).to.eql('object')
                expect(res.body._id.length).to.eql(24)
                expect(res.body._id).to.eql(id)
                done()
            })
    })
    // --- 测试 get 集合
    
    it('retrieves a collection', function(done) {
        superagent.get('http://localhost:3000/collections/test')
            .end(function(e, res) {
                // console.log(res.body)
                expect(e).to.eql(null)
                expect(res.body.length).to.be.above(0)
                expect(res.body.map(function(item) {
                    return item._id
                })).to.contain(id)
                done()
            })
    })
    // --- 测试 update 更新
    
    it('updates an object', function(done) {
        superagent.put('http://localhost:3000/collections/test/' + id)
            .send({
                name: 'Peter',
                email: 'peter@yahoo.com'
            })
            .end(function(e, res) {
                expect(e).to.eql(null)
                done()
            })
    })
    
    // --- 验证更新后的数据
    
    it('checks an updated object', function(done) {
        superagent.get('http://localhost:3000/collections/test/' + id)
            .end(function(e, res) {
                // console.log(res.body)
                expect(e).to.eql(null)
                expect(typeof res.body).to.eql('object')
                expect(res.body._id.length).to.eql(24)
                expect(res.body._id).to.eql(id)
                expect(res.body.name).to.eql('Peter')
                done()
            })
    })
    
    // --- 测试 remove 删除

    it('removes an object', function(done) {
        superagent.del('http://localhost:3000/collections/test/' + id)
            .end(function(e, res) {
                // console.log(res.body)
                expect(e).to.eql(null)
                expect(res.body.msg).to.eql('success')
                done()
            })
    })
})

运行测试

代码语言:javascript
复制
./node_modules/mocha/bin/mocha express.test.js

运行的结果一定是全部失败,因为还没有编写实际代码,下面就编写代码,使测试一个个的通过。

编写api

express.js 内容:

代码语言:javascript
复制
var express = require('express'),
  mongoskin = require('mongoskin'),
  bodyParser = require('body-parser')  

var app = express()

app.use(bodyParser())

var db = mongoskin.db('mongodb://@localhost:27017/test-rest', {safe:true})

app.param('collectionName', function(req, res, next, collectionName){
  req.collection = db.collection(collectionName)
  return next()
})

app.get('/', function(req, res) {
  res.send('欢迎')
})

// --- 后续功能代码区域

// -----------------

app.listen(3000)

上面是最基础的代码,连接到了数据库,启动了http服务

运行

代码语言:javascript
复制
node express.js

如果安装了 supervisor,就使用它来启动,之后改动 express.js 的话就不用重新启动了

代码语言:javascript
复制
supervisor express.js

启动后使用浏览器访问

代码语言:javascript
复制
http://localhost:3000/

可以看到欢迎信息,基础做好了,开始编写功能代码

添加 post 创建对象

在功能代码区添加:

代码语言:javascript
复制
app.post('/collections/:collectionName', function(req, res, next) {
  req.collection.insert(req.body, {}, function(e, results){
    if (e) return next(e)
    res.send(results)
  })
})

如果没使用 supervisor,记得重新执行 node express.js

执行测试

代码语言:javascript
复制
./node_modules/mocha/bin/mocha express.test.js

测试运行结果:

代码语言:javascript
复制
  express rest api server
    ✓ post object (41ms)
    1) retrieves an object
    2) retrieves a collection
    3) updates an object
    4) checks an updated object
    5) removes an object


  1 passing (81ms)
  5 failing

post 功能通过了

添加 get 根据ID取得对象信息

代码语言:javascript
复制
app.get('/collections/:collectionName/:id', function(req, res, next) {
  req.collection.findById(req.params.id, function(e, result){
    if (e) return next(e)
    res.send(result)
  })
})

重启、测试,结果:

代码语言:javascript
复制
  express rest api server
    ✓ post object (97ms)
    ✓ retrieves an object
    1) retrieves a collection
    2) updates an object
    3) checks an updated object
    4) removes an object


  2 passing (179ms)
  4 failing

添加 get 获取集合数据

代码语言:javascript
复制
app.get('/collections/:collectionName', function(req, res, next) {
  req.collection.find({} ,{limit:10, sort: [['_id',-1]]}).toArray(function(e, results){
    if (e) return next(e)
    res.send(results)
  })
})

重启、测试,结果:

代码语言:javascript
复制
  express rest api server
    ✓ post object (90ms)
    ✓ retrieves an object
    ✓ retrieves a collection
    1) updates an object
    2) checks an updated object
    3) removes an object


  3 passing (179ms)
  3 failing

添加 update 根据ID修改对象数据

代码语言:javascript
复制
app.put('/collections/:collectionName/:id', function(req, res, next) {
  req.collection.updateById(req.params.id, {$set:req.body}, function(e, result){
    if (e) return next(e)
    res.send(result)
  })
})

重启、测试,结果:

代码语言:javascript
复制
  express rest api server
    ✓ post object (128ms)
    ✓ retrieves an object
    ✓ retrieves a collection
    ✓ updates an object
    ✓ checks an updated object
    1) removes an object


  5 passing (230ms)
  1 failing

添加 delete 根据ID删除对象

代码语言:javascript
复制
app.del('/collections/:collectionName/:id', function(req, res, next) {
  req.collection.removeById(req.params.id, function(e, result){
    if (e) return next(e)
    res.send((result===1)?{msg:'success'}:{msg:'error'})
  })
})

重启、测试,结果:

代码语言:javascript
复制
  express rest api server
    ✓ post object (40ms)
    ✓ retrieves an object
    ✓ retrieves a collection
    ✓ updates an object
    ✓ checks an updated object
    ✓ removes an object


  6 passing (103ms)

这样,所有测试都就通过了,代码开发完成

小结

通过这个小例子,可以了解nodejs express的开发方式,并体验了测试驱动的开发方法

如果您感觉在公众号文章中不方便练习,可获取PDF版本

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-01-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 JAVA高性能架构 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 教程内容
  • 前期准备
  • 创建项目
    • 安装依赖
      • 新建代码文件
      • 编写测试
        • 运行测试
        • 编写api
          • 运行
            • 添加 post 创建对象
              • 添加 get 根据ID取得对象信息
                • 添加 get 获取集合数据
                  • 添加 update 根据ID修改对象数据
                    • 添加 delete 根据ID删除对象
                    • 小结
                    相关产品与服务
                    云数据库 MongoDB
                    腾讯云数据库 MongoDB(TencentDB for MongoDB)是腾讯云基于全球广受欢迎的 MongoDB 打造的高性能 NoSQL 数据库,100%完全兼容 MongoDB 协议,支持跨文档事务,提供稳定丰富的监控管理,弹性可扩展、自动容灾,适用于文档型数据库场景,您无需自建灾备体系及控制管理系统。
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档