当前位置: 首页 > 工具软件 > mongoskin > 使用案例 >

第8章-使用Express.js和Hapi构建Node.js-REST-API服务-8.3.使用Express和Mongoskin实现REST API服务器

颜哲彦
2023-12-01

创建index.js作为程序的入口文件
//1.引入依赖

var express = require('express'),
  mongoskin = require('mongoskin'),
  bodyParser = require('body-parser'),
  logger = require('morgan')

//2.创建一个服务器对象

var app = express()

//3.使用bodyParser.urlencoded()bodyParser.json()两个中间件从响应体中提取参数和数据。通过app.use()函数调用这些中间件

app.use(bodyParser.urlencoded())
app.use(bodyParser.json())
app.use(logger())//中间件express.logger()并不是必需的,他的作用是方便我们监控请求

//4.格式:

mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]
var db = mongoskin.db('mongodb://@localhost:27017/test', {safe:true})
var id = mongoskin.helper.toObjectID//将十六进制字符串转化为MongoDB ObjectID数据类型

//5.app.param()方法是Express.js中间件的另一种形式。当URL中出现对应的参数时进行一些操作(本例如:当RUL中出现以冒号开头的collectionName时,我们会选择一个特定的集合)

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

//6.添加根目录访问响应

app.get('/', function(req, res, next) {
  res.send('Select a collection, e.g., /collections/messages')
})

//7.根据5中app.param()中间件,给我们提供了req.collection对象,他指向数据库中一个特殊的集合

app.get('/collections/:collectionName', function(req, res, next) {
  req.collection.find({}, {limit: 10, sort: [['_id', -1]]})//返回10条,_id属性排序
    .toArray(function(e, results){
      if (e) return next(e)
      res.send(results)
    }
  )
})

//8.我们只需把整个请求传给MongoDB就行。
//这种方法或者叫架构,通常被称作“自由JSON格式的REST API”
//因为客户端可以抛出任意格式的数据,而服务器总能进行正常的响应

app.post('/collections/:collectionName', function(req, res, next) {
  req.collection.insert(req.body, {}, function(e, results){
    if (e) return next(e)
    res.send(results)
  })
})

//9.检索单一对象的方法比find()方法速度更快,他们使用的是不同的接口
//findOne()会直接返回结果对象,而不是句柄
//借助Express.js从:id中提取ID参数,他被保存在req.params.id中

app.get('/collections/:collectionName/:id', function(req, res, next) {
  req.collection.findOne({_id: id(req.params.id)}, function(e, result){
    if (e) return next(e)
    res.send(result)
  })
})

//10.PUT请求的,update()方法返回的不是变更的对象,而是变更对象的计数
//{$set: req.body}是一种特殊的MongoDB操作(操作名以$符开头),他用来设置值
//第二个参数{safe: true, multi: false}是一个保存配置的对象,他用来告诉MongoDB,等到执行结束后才运行回调,并且只处理一条(第一条)请求

app.put('/collections/:collectionName/:id', function(req, res, next) {
  req.collection.update({_id: id(req.params.id)},
    {$set: req.body},
    {safe: true, multi: false}, function(e, result){
    if (e) return next(e)
    res.send((result === 1) ? {msg:'success'} : {msg:'error'})
  })
})

//11.返回定义好的JSON格式的信息(JSON对象包含一个msg属性,当处理成功时他的内容是字符串success,如果处理失败则是编码后的错误消息)
//注:在Express.js中,app.del()方法是app.delete()方法的一个别名

app.del('/collections/:collectionName/:id', function(req, res, next) {
  req.collection.remove({_id: id(req.params.id)}, function(e, result){
    if (e) return next(e)
    res.send((result === 1) ? {msg:'success'} : {msg:'error'})
  })
})

//12.启动服务器,监听3000端口

app.listen(3000, function(){
  console.log ('Server is running')
})

二、运行实例

在命令行执行:
$node . 等价于$node index

然后新开一个命令行窗口(前面一个不要关),运行测试程序:

$mocha test

如果希望得到一个更好看的结果报告,可以运行下面这个命令

$mocha test -R nyan

如果不喜欢Mocha或者BDD(和TDD),CURL是另一种可选方案,他的使用方式:

curl http://localhost:3000/collections/curl-test

POST请求:$curl -d "name=lijian&email=374452668@qq.com" http://localhost:3000/collections/curl-test
DELETE和PUT请求需要使用参数–request NAME,如:

$curl --request DELETE http://localhost:3000/collections/curl-test/52f6828a23985a6565000008

还可以使用浏览器来发起GET请求:http://localhost:3000/test

三、总结

很多时候测试代码比应用本身的代码要多,但是我们应该要相信磨刀不误砍柴工,多使用TDD去进行开发。

附:
测试驱动开发是敏捷开发中的一项核心实践和技术,也是一种设计方法论。TDD的原理是在开发功能代码之前,先编写单元测试用例代码,测试代码确定需要编写什么产品代码。TDD虽是敏捷方法的核心实践,但不只适用于XP(Extreme Programming),同样可以适用于其他开发方法和过程。
TDD的基本思路就是通过测试来推动整个开发的进行,但测试驱动开发并不只是单纯的测试工作,而是把需求分析,设计,质量控制量化的过程。
TDD的重要目的不仅仅是测试软件,测试工作保证代码质量仅仅是其中一部分,而且是在开发过程中帮助客户和程序员去除模棱两可的需求。TDD首先考虑使用需求(对象、功能、过程、接口等),主要是编写测试用例框架对功能的过程和接口进行设计,而测试框架可以持续进行验证

 类似资料: