动词 or 名词 :这是一个问题 【转载】
前言:有网友让我用通俗的语言来讲一讲RESTful , 我在这一块工程实践的不太多,有点为难了, 只能讲一讲我的理解, 欢迎大家批评指正。计算机行业最擅长造新词了,像什么AJAX,IoC, AOP, SOA, NoSQL, 微服务,TDD,敏捷,RESTful......等等。
有很多人非常喜欢在口头拽这些热门名词,显得多么高深的样子, 其实这些热词背后代表的东西,要解决的问题没那么复杂,很多人是由于带着敬畏心被吓住了。
RESTful就是其中之一, 它不是一个新的计算机语言或者技术, 只是一个架构风格, 准确一点讲是如何设计系统来对外提供服务。
传统网站我在2000年左右还是微软粉丝,一直用ASP + COM 写Web网站, 当时的网站是单纯的HTML, 只有一点javascript效果, 这些网站基本上是自治的“独立王国”, 不会通过API接口对外提供服务。
由于在浏览器中通过javascript来异步访问后端接口的极少, AJAX这个热词还没有出现, 所以当时在ASP中主要处理两个东西:图1 : 常见的网站操作很普通,对吧? 其实现在大部分网站还是这么做的。 SOA后来互联网大发展, 各个网站系统变的越来越复杂,一个自治的“帝国”经常要被划分成多个“王国”,这些王国之间如何沟通和交流变得重要起来。
一些大厂商顺势制定了叫做SOA的标准,提出了面向服务的架构体系。
和面向对象这样的技术术语不同 , SOA中的服务其实是业务层面的东西, 是个业务活动的逻辑表达方式,粒度更粗一些。
这些服务独立于厂商,产品和具体实现技术, 能够发布出来被别的系统调用, 还能够被组合起来形成更粗粒度的“服务”。
虽然服务是面向业务的, 但还得用具体的技术表达出来, 毫无意外, 大佬们选择了XML, 用XML来描述一个服务看起来来像这个样子:
图2: 服务描述片段
没有玩过Web Service 的不用完全看懂它,它描述的也是一个getBook这样的操作, 输入是一个id ,类型是字符串。
返回值也是一个字符串 (通常是XML格式的,表示书籍的详细信息)
我想突出的重点是这个服务(getBook)和 “图1" 中的getBook.action 在形式上的一致性:
他们都试图表达这样一个过程: 获得一本书的信息, 所以这两种方式都是面向过程的。或者说,他们都以动词为主, getBook, addBook, deleteBook , placeOrder, registerUser, login , transfer 等等。
RESTful其实面向过程,以动词为主的方式是最自然的方式, 码农不用怎么费脑子就能想到如何设计。
然后RESTful 这种概念就漂洋过海,从美国杀入了中国市场。
RESTful告诉大家说: 以后你们不要用动词, 用名词更好, 不要面向过程了, 要面向资源(Resource)。 资源使用一个URI来表达的, 例如 :图3 : REST风格的资源
注意图3 中的books, orders, 这些都是名词, 那问题自然就来了: 我怎么做传统的add, delete等操作呢?
RESTful 说: 要充分利用HTTP 提供的方法:图4: 对资源的操作
你看增删改查都齐全了。
需要注意的是服务器端返回信息的格式由发起调用的客户端指定,例如HTML ,JSON, XML, 这称为资源的表述(representation)
我第一次看到这种方式的时候大为震惊, 这实在是太不直观了。
按照这种风格,你需要把服务器端的东西都 ”资源化“, 像上面的那些很容易, 还有一些例如转账,登录,忘记密码,获取短信验证码,这样常见的业务操作“资源化”起来就不那么爽了。
RESTful 架构风格还要求Stateless(无状态), 服务器端并不会维护/保存会话(session)信息, 这些会话信息应该有客户端来维持,每次请求时也需要一并发送到服务器端。
服务器端甩掉了会话状态这个大包袱,一下子就轻松多了,可扩展性会有极大提升, 例如我可以把一个服务部署到由100个服务器组成的集群中,每个服务器都可以处理用户的请求。
假设用户第一个请求发到了服务器#87 ,然后这个服务器坏了, 第二次请求可以发送到剩下99个服务器中的任何一台, 反正会话信息包含在每个请求中, 任意一台服务器都能处理。
我认为RESTful的无状态是一种理想的境界,现实中不大容易做到, 客户端到底如何保存session信息呢,是每次请求都把用户名/密码 发到服务器端还是通过第三方认证的方式实现?
如果想实现一个购物车的应用, 服务器不保存session的话该怎么做? 我这块儿实践不多,请高手不吝赐教。
虽然有难度, 那为什么现在很多人对REST趋之若鹜呢?
我个人认为大家是看中了他的轻量级的风格, 那就是用HTTP+JSON就可以搞定一切。
传统的SOA倾向于用WSDL来描述服务, 用SOAP协议来访问服务,此外还有服务注册,发现, 组合,总线,安全等一系列问题, 通常还得上Websphere ,WebLogic 这样重量级的服务器。
码农不仅要问了: 我就想调用一个简单的接口, 搞这么麻烦干嘛?
REST一来, 写个Web服务简直是太简单了, 用一个最“低级”的java servlet, 分分钟搞定, 不过有时候大家也没有严格的遵循REST的要求, 没有把一切东西都“资源化”,因为那样太不容易了。
我看到的很多项目号称是REST风格, 但其实就是通过HTTP和JSON对外提供的服务而已 ,没有完整的遵循REST架构风格的约束, 可以说是“挂着REST的羊头,卖着面向过程的狗肉”。
最后,推荐大家去读一下RESTful架构风格的提出者Roy Fielding 博士的论文, 2000年发表的《架构风格与基于网络的软件架构设计》, 这是RESTful开山之作, 也是Web发展史上非常重要的一篇文献。
(完)
声明:原创文章,未经授权,禁止转载
你看到的只是冰山一角, 更多精彩文章,尽在“码农翻身” 微信公众号, 回复消息"m"或"目录" 查看更多文章
http://mp.weixin.qq.com/s?__biz=MzAxOTc0NzExNg==&mid=2665513217&idx=1&sn=a56253effadfc14d428966e0dbc9962b#rd
动词 or 名词 :这是一个问题 【转载】的更多相关文章
- nginx学习笔记(7)Nginx如何处理一个请求---转载
如何防止处理未定义主机名的请求基于域名和IP混合的虚拟主机一个简单PHP站点配置 基于名字的虚拟主机 Nginx首先选定由哪一个虚拟主机来处理请求.让我们从一个简单的配置(其中全部3个虚拟主机都在端口 ...
- [转载]C++命名规则
在软件开发这一高度抽象而且十分复杂的活动中,命名规则的重要性更显得尤为突出.一套定义良好并且完整的.在整个项目中统一使用的命名规范将大大提升源代码的可读性和软件的可维护性. 在引入细节之前,先说明一下 ...
- 工程实践:给函数取一个"好"的名字
工程实践:给函数取一个"好"的名字 早在2013年,国外有个程序员做了一个有意思的投票统计(原始链接请见:<程序员:你认为最难做的事情是什么?>),该投票是让程序员从以 ...
- Objective-C开发编码规范【转载】
概要 Objective-C是一门面向对象的动态编程语言,主要用于编写iOS和Mac应用程序.关于Objective-C的编码规范,苹果和谷歌都已经有很好的总结: Apple Coding Guide ...
- C++编程命名规则(转载)
原文地址:http://www.cnblogs.com/ggjucheng/archive/2011/12/15/2289291.html 如果想要有效的管理一个稍微复杂一点的体系,针对其中事物的一套 ...
- java开发命名规范(转载)
java开发命名规范 使用前注意事项: 1. 由于Java面向对象编程的特性, 在命名时应尽量选择名词 2. 驼峰命名法(Camel-Case): 当变量名或函式名是由一个或多个单字连结在一起,而 ...
- 正则语言引擎:一个简单LEX和YACC结合运用的实例
本文先描述了LEX与YACC的书写方法.然后利用LEX与YACC编写了一个简单正则语言的引擎(暂时不支持闭包与或运算),生成的中间语言为C语言. 正则引擎应直接生成NFA或DFA模拟器的输入文件,但在 ...
- C++命名规则 (转载仅作参考)
如果想要有效的管理一个稍微复杂一点的体系,针对其中事物的一套统一.带层次结构.清晰明了的命名准则就是必不可少而且非常好用的工具. 活跃在生物学.化学.军队.监狱.黑社会.恐怖组织等各个领域内的大量有识 ...
- 转:如何实现一个malloc
如何实现一个malloc 转载后排版效果很差,看原文! 任何一个用过或学过C的人对malloc都不会陌生.大家都知道malloc可以分配一段连续的内存空间,并且在不再使用时可以通过free释放掉. ...
随机推荐
- Linux环境下实现生产者消费者问题
#include <stdio.h> #include <semaphore.h> #include <stdlib.h> #include <pthread ...
- Servlet 编程 请求的转发
在上篇的基础上,修改servlet *转发只能在同一应用内转发. 将forward 地址改为:youku.com 不能访问 重定向是可以访问外部应用的
- 使用Eclipse开发Java Web过程中Debug调试的使用方法
里介绍的是在Eclipse中的Debug调试. 首先右击项目选择Debug As -- Debug on Server 或者点击Server面板的小昆虫图标,启动Debug模式. 运行web项目,进行 ...
- redis 应用场景
1.string类型 : 图片和视频文件,静态文件 2.list 双向链表:回帖ID,我的关注列表,消息队列 length = redis.lpush('users:newest', 'user:go ...
- wajueji
#include<stdio.h>int map[3]={42,3,99};int step[3]={0};int max=99999;void qian(){ int i=0; int ...
- C++ builder的文件操作
在编程的过程中,文件的操作是一个经常用到的问题,在C++Builder中,可以使用多种方法对文件操作,下面我就按以下几个部分对此作详细介绍,就是:1.基于C的文件操作:2.基于C++的文件操作:3.基 ...
- Delphi 指针
1:指针的赋值. type RTestInfo = record Age:Integer; end; PtestInfo = ^ RtestInfo; var Test1,Test2:PtestInf ...
- phpcms标签整理_当前栏目调用
phpcms标签整理_当前栏目调用 转载 **//SQL语句调用: {pc:get sql="select * from phpcms_category where catid in($ca ...
- Redis学习笔记(5)-Set
package cn.com; import java.util.HashMap; import java.util.Map; import java.util.Set; import redis.c ...
- C++线程池的实现(二)
参考文章:http://blog.csdn.net/huyiyang2010/archive/2010/08/10/5801597.aspx // CThread.h #ifndef __MY_THR ...