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