写在前面的话

这个问题看起来就显得有些萌,或者说类似的问题都有些不靠谱,世上哪有那么多一定的事情,做开发都不一定做多久呢,所以说如果你有这个疑问的话是真真有点儿不着调,不过可能也就是随口一问吧,没有深究的必要。既然有人问这个,那么就再用一篇文章谈谈RESTful吧,既然谈,就不能只是谈其优点,也不能一味的吹捧,也讲一下自己的一些理解和不足的地方。

规范、易读、简洁?

Spring+SpringMVC+MyBatis+easyUI整合进阶篇(一)设计一套好的RESTful API
Spring+SpringMVC+MyBatis+easyUI整合进阶篇(二)RESTful API实战笔记(接口设计及Java后端实现)
Spring+SpringMVC+MyBatis+easyUI整合进阶篇(三)使用ajax方法实现form表单的提交
Spring+SpringMVC+MyBatis+easyUI整合进阶篇(四)RESTful API实战笔记(前端代码修改)
前文中已经谈了RESTful不少的优点,也做了代码更新,首先,REST强调HTTP应当以资源为中心,并且规范了资源URI的风格;规范了HTTP请求动作(PUT,POST等)的使用,具有对应的语义;遵循REST规范的Web应用将会获得下面好处:URL具有很强可读性的,具有自描述性;资源描述与视图的松耦合;可提供OpenAPI,便于第三方系统集成,提高互操作性;如果提供无状态的服务接口,可提高应用的水平扩展性;

总结下来:规范、易读,但是这两个优点也带来一些不尽如人意的"反效果":

  • 因为RESTful规范较为明确且有一定的"强制性",这种限制反而导致设计uri变得复杂了,尤其是复杂的关系,操作,资源集合,硬性套用rest原则设计非常困难。
  • 对于RESTful的争论无处不在,都在讨论正确性和规范性,即使和同事之间也会有类似的争执,当我们在争论Restful风格到底如何设计才是正宗时,发现心中的困惑不仅没有降低,反而增加了。
  • RESTful思想及其所倡导的规范很正确,但是使用者的行为太刻意了反而导致这个东西变了味道,争来争去就是为了证明自己的理解和使用最"正宗"。

RESTful中的模棱两可

前一个段落可能有些过于概念化了,还是举一些具体的例子吧。

案例一

其实,RESTful中也存在着许多的模棱两可,也有很多不是那么让开发人员舒服的地方,有人会去纠结查询、增加、修改、删除(对应的方法就是get、post、put、delete),个人认为这并不完全正确,因为这个想法把开发工作中的业务场景过于简单化和模板化了,我们开发的功能就只实现这四类操作吗、如果遇到一些不能完全对应上这四种方式的业务该怎么办呢?

  • 发短信、支付、用户登录认证,该用get、post、put、delete中的哪一个HTTP动词?
  • login和logout应该怎么REST化?
  • 验证码发送该如何定义uri?

类似的问题还有很多,感觉很多朋友会遇到类似的问题,心里面也有一些不确定该如何去做,其实在理解了REST后,这些并不是什么无解的难题,只是思维方式要转换一下: login和logout其实只是对session资源或者cookie资源的创建和删除;业务的uri如何选择HTTP动词也要灵活变通,规范是死的,人是活的,按照自己的理解去做,如果后期发现错误即使纠正就好了。不过,虽然API如何编写是开发者的自由,但如果一个API在url里放一堆动词、资源设计混乱、各种乱用HTTP Method和Status Code,就太不像话了,规范嘛还是要遵守的,说了这么多理解上的偏差,其实代码质量才是最重要的,有些手段其实只是让代码看起来比较优雅的手段而已。

案例二

以上是针对于RESTful理解和设计上的一个例子,具体工作中还有其他的例子吗?也是很多的,比如,比较棘手的一个问题:跨域资源共享 CORS。

在实际进行跨域请求时,经常会遇到类似 No 'Access-Control-Allow-Origin' header is present on the requested resource.这样的报错:

这个问题并不是因为RESTful引起的,也不能通过修改RESTful的规范去解决,举这个例子的原因是因为在接口的RESRful化时也遇到过这个问题,解决办法就不在本文中列举了,有兴趣的朋友可以看一下跨域资源共享 CORS 详解这篇文章,以后有时间会把解决方案整理出来的。

一些需要重视的安全性问题

当然,不止是以上的两个问题,前一个段落主要是讲述了一下理解和具体使用上的问题,这一段讲一下可能引发的安全性问题。

遗漏了对资源从属关系的检查

一个典型的RESTful的URL会用资源名加上资源的id编号来标识其唯一性,就像这样:/users/{userid},例如:/users/100

一般而言用户只能查看自己的用户信息,而不允许查看其它用户的信息。在这种情况下,攻击者很可能会尝试把这个URL里面的USER ID从100修改为其他数值,以期望应用返回指定用户的信息。不过由于这个安全风险太显而易见,绝大多数应用都会对当前请求者的身份进行校验,看其是否是编号为100的用户,校验成功才返回URL中指定的用户信息,否则会拒绝当前请求。

不经意间泄露的业务信息

以查看用户信息的RESTful URL为例:/users/100。由于用户ID是一个按序递增的数字,因此攻击者既可以通过ID知道目前应用中的用户规模,也可以分别在月初和月末的时候注册一个用户,并对比两个用户的ID即可知道当前这个月有多少新增用户。同理,如果订单号也是按序自增的数字,攻击者可以了解到一定时间范围内的订单量。

这类ID并不会给应用造成任何技术上的威胁,只是通过ID泄露出来的信息对于你的业务而言可能非常敏感。解决办法是不使用按序递增的数字作为ID,而是使用具有随机性、唯一性、不可预测性的值作为ID,最常见的做法就是使用UUID。

参考RESTful架构风格下的4大常见安全问题

选择适合自己的方式

Spring+SpringMVC+MyBatis+easyUI整合进阶篇(五)记录一下从懵懂到理解RESTful的过程
前一篇博客中也提到了很多其他的方式,比如传统的MVC开放形式,比如webservice,比如rpc调用,RESTful也只是其中的一种而已,这些选项中并没有高下之分,无非是多种约定俗成的标准,传统MVC开发着舒服就按MVC模式来开发,习惯用RPC就用RPC,能理解和接受REST就用REST。

前几篇文章中描述了RESTful那么多的优点,现在又说大可不必使用,前文又提到RESTful是好的设计实践,现在又是另外一种说法,不是自相矛盾吗?

这是我的文章,我肯定要按照我的一些想法写啊,可能有不对的地方,前文中提到的是好的设计实践也是我的个人想法和理解,这篇的开头就说了,不能只谈优点,所以又列举了一些不足吧,我写文章不是挑口水,很没必要,选择适合自己的技术和规范就好。

套用网络上比较流行的一句话:

听了很多道理却依然过不好一生。

作为一名开发人员,自己动手去实践才是硬道理,别人说什么都不要全盘接受,你要想想适不适合你,适不适合你目前做的项目,鞋合不合适只有脚知道,just do it!

结语

优点也好,缺点也罢,虽然看似也总结了不少,但都是个人见解,肯定还有一些遗漏的地方没有讲清楚,还请见谅。

回答文章一开始的问题,是不是一定要用呢?是不是一定要遵循其规则呢?如果不能解决你所面对的问题,不能提高和提升代码质量、提升工作效率,其实大可不必如此介怀,不用就是了。

首发于我的个人博客,编辑于2017年10月13日晚11:37分。

有人提了一个问题:一定要RESTful吗?的更多相关文章

  1. 给JDK提的一个bug(关于AbstractQueuedSynchronizer.ConditionObject)

    1. 背景 之前读JUC的AQS源码,读到Condition部分,我当时也写了一篇源码阅读文章--(AbstractQueuedSynchronizer源码解读--续篇之Condition)[http ...

  2. 构建一个基于 Spring 的 RESTful Web Service

    本文详细介绍了基于Spring创建一个“hello world” RESTful web service工程的步骤. 目标 构建一个service,接收如下HTTP GET请求: http://loc ...

  3. Apache CXF实现Web Service(2)——不借助重量级Web容器和Spring实现一个纯的JAX-RS(RESTful) web service

    实现目标 http://localhost:9000/rs/roomservice 为入口, http://localhost:9000/rs/roomservice/room为房间列表, http: ...

  4. 为什么一个Http Header中的空格会被骇客利用 - HTTP request smuggling

    figure:last-child { margin-bottom: 0.5rem; } #write ol, #write ul { position: relative; } img { max- ...

  5. Redis Cluster架构优化

    Redis Cluster架构优化 在<全面剖析Redis Cluster原理和应用>中,我们已经详细剖析了现阶段Redis Cluster的缺点: 无中心化架构 Gossip消息的开销 ...

  6. Neutron 理解 (4): Neutron OVS OpenFlow 流表 和 L2 Population [Netruon OVS OpenFlow tables + L2 Population]

    学习 Neutron 系列文章: (1)Neutron 所实现的虚拟化网络 (2)Neutron OpenvSwitch + VLAN 虚拟网络 (3)Neutron OpenvSwitch + GR ...

  7. FIN_WAIT1 能持续多久?你知道吗

    FIN_WAIT1 能持续多久?你知道吗 2016-01-12 运维帮 原文:http://blogread.cn/it/article/7215?f=wb&luicode=10000359 ...

  8. [转]把项目从VS2005升级到VS2013

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://rangercyh.blog.51cto.com/1444712/1394348 ...

  9. 关于FIN_WAIT1

    前些天,一堆人在 TCPCopy 社区里闲扯蛋,有人提了一个问题:FIN_WAIT1 能持续多久?引发了一场讨论,期间我得到斌哥和多位朋友的点化,受益良多. 让我们热热身,通过一张旧图来回忆一下 TC ...

随机推荐

  1. 阿里云Prismplayer-Web播放器的使用

    Prismplayer是一套在线视频播放技术方案,同时支持Flash和Html5两种播放技术,可对播放器进行功能配置和皮肤定制.其在线使用文档地址为:https://help.aliyun.com/d ...

  2. windows下使用密钥登录Linux及xshell代理转发

    1.密钥登录原理 一般我们使用xshell访问远程主机(Linux主机)时,都是先请管理员给我们开一个账户,即为我们设置一个一个用户名和对应的密码,然后我们就可以使用下面的方式登录到远程主机了: 在这 ...

  3. 【1414软工助教】团队作业7——Alpha冲刺之事后诸葛亮 得分榜

    题目 团队作业7--Alpha冲刺之事后诸葛亮 往期成绩 个人作业1:四则运算控制台 结对项目1:GUI 个人作业2:案例分析 结对项目2:单元测试 团队作业1:团队展示 团队作业2:需求分析& ...

  4. 团队作业8——Beta 阶段冲刺7th day

    一.当天站立式会议 二.每个人的工作 (1)昨天已完成的工作(具体在表格中) 完善支付功能 (2)今天计划完成的工作(具体如下) 测试与正式发布 (3) 工作中遇到的困难(在表格中) 成员 昨天已完成 ...

  5. 201521123074 《Java程序设计》第3周学习总结

    1.本周学习总结 用百度脑图画了一张,点开图片全屏就可以看清楚了 脑图链接 2.书面作业 Q1.代码阅读 以下代码可否编译通过?哪里会出错?为什么?尝试改正? 如果创建3个Test1对象,有内存中有几 ...

  6. 201521123010 《Java程序设计》第14周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多数据库相关内容. 2. 书面作业 1. MySQL数据库基本操作 建立数据库,将自己的姓名.学号作为一条记录插入.(截图,需出现自 ...

  7. Core Java 简单谈谈HashSet

    同学们在看这个问题的时候,我先提出者两个问题,然后大家带着问题看这个文章会理解的更好. HashSet为什么添加元素时不能添加重复元素? HashSet是否添加null元素? 打开源码, 我们看到如下 ...

  8. 读取指定excel,修改并某个值并另存到指定路径

    HSSFWorkBook是解析excel2007以前的版本(xls)之后的版本使用XSSFWrokBook(xlsx) 附:处理excel2007之后的版本代码: package gbyp.autoQ ...

  9. Log4j.properties属性文件

    log4j.properties文件属性介绍log4j.rootLogger = [ level ] , appenderName1, appenderName2, …#level : 设定日志记录的 ...

  10. Server Tomcat v7.0 Server at localhost failed to start.解决方法

    ---恢复内容开始--- 今天在做jsp项目的时候,Tomcat突然无法打开了,出现的报错是这样的: 也不知道是怎么搞得,百度了老半天看到有的网友是通过两这个方法解决的,连接在这http://blog ...