RESTful理解

什么是REST?什么又是RESTful?node.js如何实现REST架构?

REST与RESTful

REST与RESTful这几年来一直充斥在各大博客与技术论坛中,它们是何方神圣呢?其实REST并不是一种新的技术,而是一种软件架构的设计风格,全称是REpresentational State Transfer,是由http协议主要设计者Fielding在一篇论文中提到,从而引起大家的关注,并且得到实现和推广。前面所说REST是一种软件架构的设计风格,那么凡是符合REST设计的架构称为RESTful架构。

REST是什么?

刚才说到REST是REpresentational State Transfer的缩写,中文意思是表现层(资源)的状态转变,什么是资源?网络上的任何一个实体都是资源,包括文字、图片、音频、视频等等你所能想到的,我们知道如果我需要获取一张图片,那么我需要通过URI(通用资源标识符)来获取它,并且这个URI是独一无二的。那么对于“状态转变”又如何理解呢,其实对于数据库操作来说,我们无非就四种基本操作,增删改查,那么对于资源的交互来说,一样是存在这四种状态,增删改查。

REST是怎么样一种风格?

看了上面,你或许还是云里雾里,仅仅只是了解了REST是怎么一个概念,甚至对于这个概念的了解程度也只是停留在表面,那么接下来我们就深入点介绍这种设计风格。假如我们数据库有这样的数据:

1
2
3
4
5
6
7
8
9
10
11
12
var books = {
'book_1':{
'id' : 1,
'name':'javascript高级程序设计',
'money':'99rmb'
},
'book_2':{
'id':2,
'name':'javascript权威指南',
'money':'100rmb'
}
}

我们先用之前的设计习惯来说,后台这时候会定义一个getBookList,定义updateBook等等接口操作来对于数据库进行增删改查操作,然后前端通过ajax等方式调用这些接口来达到目的。对于REST来说,book其实就是我们所说的资源,然后它的状态也同样是增删改查,REST只用/book/这个来作为接口地址,然后通过http协议的动作来表示状态层的改变,我们都知道http协议有4个比较重要的动作,GET\POST\PUT\DELETE(我们最常用的是GET和POST),看下下表:

资源GETPOSTPUTDELETE
一组资源的 URI,比如 http://www.example.com/book/列出 URI 及该资源组中每个资源的详细信息使用一组给定的资源替换当前整组资源在本组资源中创建 / 追加一个新资源删除整组资源
单个资源的 URI,比如 http://www.example.com/book/1获取给定资源的详细信息替换 / 创建指定的资源,并将其追加到相应的资源组把指定的资源作为资源组,并在其下创建 / 追加一个新元素,使其隶属于当前资源删除指定元素

从上表我们可以很清楚地看到,我们的REST的URI只是表示了一个资源,或者说是一个名词,并没有带任何的动作,所有的动作都是通过http协议来实现。

nodejs实现RESTful

那么如何使用nodejs来实现呢RESTful?看看下面的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
var express = require('express') //加载模块  
var app = express() //实例化之

var books = {
'book_1':{
'id' : 1,
'name':'javascript高级程序设计',
'money':'99rmb'
},
'book_2':{
'id':2,
'name':'javascript权威指南',
'money':'100rmb'
}
}
app.get('/books',function(req, res){ //Restful Get方法,查找整个集合资源
res.set({'Content-Type':'text/json','Encodeing':'utf8'});
res.send(books)
})
app.get('/books/:id',function(req, res){ //Restful Get方法,查找一个单一资源
res.set({'Content-Type':'text/json','Encodeing':'utf8'});
res.send(books['book_'+req.param('id')])
})
app.post('/books/', express.bodyParser(), function(req, res){ //Restful Post方法,创建一个单一资源
res.set({'Content-Type':'text/json','Encodeing':'utf8'});
books['book_'+req.body.id] = req.body
res.send({status:"success",url:"/books/"+req.body.id}) //id 一般由数据库产生
})
app.put('/books/:id', express.bodyParser(), function(req, res){ //Restful Put方法,更新一个单一资源
res.set({'Content-Type':'text/json','Encodeing':'utf8'});
books['book_'+req.body.id] = req.body
res.send({status:"success",url:"/books/"+req.param('id'),books:req.body});
})
app.delete('/devices/:id',function(req, res){ //Restful Delete方法,删除一个单一资源
res.set({'Content-Type':'text/json','Encodeing':'utf8'});
delete books['book_'+req.param('id')]
res.send({status:"success",url:"/books/"+req.param('id')})
})
app.listen(8888);

结语

我们会发现,使用RESTful来设计api接口的话,会很简洁,对于不同的语言都可以适用,能够起到一个规范的作用,至于其他的应用,还需要进一步的探索。