创建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-testPOST请求:$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首先考虑使用需求(对象、功能、过程、接口等),主要是编写测试用例框架对功能的过程和接口进行设计,而测试框架可以持续进行验证