http://blog.csdn.net/zhutulang/article/details/52029169
经常听到rest风格api这个词,那么到底什么是rest api呢?(Representational State Transfer)?表述性状态转移?《Spring实战》上说:REST就是将资源的状态已最合适的形式从服务器端转移到客户端。我在看了很多博客和资料后仍然感觉到头大,我个人感觉关于这方面的资料很混乱,当然我确实也没有那个心思去看REST提出者Roy Fielding的那篇博士论文Architectural Styles and the Design of Network-based Software Architecture
很多资料上比较混乱的地方和我比较疑惑的地方是,比如:(1)协议到底要不要带版本号呢?带的话,标准做法是放到url中还是放到header中呢?对此,很多文章各持己见。(2)很多人自称自己的做法是rest的,但是很多接口不区分增删改查都用的是post方法,或者只用get(用于查询资源),和post(用于增加、删除和修改) (3)按照“标准”,查询资源应该是get方法,可是有时候有些接口很复杂,查询参数可能有几十甚至上百个那么多,很有可能会超过get请求的url长度最大限制啊。所以,我一度怀疑rest api是否真的适用于复杂接口的设计。(4)接口的url设计到底怎样是“标准”的。比如,查询作者名为tom的、分类为文学的书籍,http://域名/books/author/tom/class/literature 还是 http://域名/books?author=tom&class=literature ,这两种那种是标准的呢?或者这两种都可以?
或者,我感觉实在是没必要钻牛角尖。那么,我就谈谈我对rest api的几点粗浅的认识吧:
(1)rest api操作的是资源,一个url就是一个资源,url中不应该出现动词
(2)rest api对资源的操作包括C(Create) R(Read) U(Update) D(Delete),即增、查、改、删,分别对应的http方法是 post、get、put 、delete。不同的接口可能对应的是同一个url,这时候不同的http方法就构成了不同的操作了。
(3)rest api是无状态的,请求之间不应该有依赖。回想常见的网站架构,用户登录后将相关信息存放到session中,该用户以后的相关操作从session中验证权限。在rest中,要放弃session的使用,每一个请求之间是独立的,每个需要鉴权的接口都要带上鉴权信息。这种无状态性有利于服务器的扩展。
下面,我简单介绍下我最近写的一个demo。
(1)项目简介
这个demo很简单,是一个记账小工程。用户可以注册、修改密码,可以记账、查找记账记录等。
(2)接口介绍
用户操作相关:
post /users 用户注册
post /users/login 用户登录(这里我把login当成一个名词)
put /users/pwd?userId=xxx&sign=xxx 用户修改密码
delete /users?uerId=xxx&sign=xxx 删除用户
记账记录操作相关:
post /records?userId=xxx&sign=xxx 增加一条记账记录
get /records/:id?userId=xxx&sign=xxx 查询一条记账记录详情
put /records/:id?userId=xxx&sign=xxx 修改一条记账记录详情
get /records?查询参数&userId=xxx&sign=xxx 分页查询记账记录
delete /records/:id?userId=xxx&sign=xxx 删除一条记账记录
(3)关于redis和数据库的说明
服务端在用户登录后,生成token,并将token保存到redis中。后面在接口鉴权的时候会取出token计算签名,进行比对。
这个demo搭建了一个redis主从复制,具体可以参考:http://download.csdn.net/detail/zhutulang/9585010
数据库使用mysql,脚本在 src/main/resources/accounting.sql
(4)项目地址
关于demo的细节这里就不在详述了,这个工程以后会再优化。demo可以在这里下载:http://download.csdn.net/detail/zhutulang/9586998