有人提了一个问题:一定要RESTful吗?

简介:

写在前面的话

这个问题看起来就显得有些萌,或者说类似的问题都有些不靠谱,世上哪有那么多一定的事情,做开发都不一定做多久呢,所以说如果你有这个疑问的话是真真有点儿不着调,不过可能也就是随口一问吧,没有深究的必要。既然有人问这个,那么就再用一篇文章谈谈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分。


本文作者:佚名

来源:51CTO

相关文章
|
6天前
|
网络协议 JavaScript 安全
第十一篇 前沿趋势与展望:深入探索GraphQL、RESTful API、WebSocket、SSE及QUIC与HTTP/3
第十一篇 前沿趋势与展望:深入探索GraphQL、RESTful API、WebSocket、SSE及QUIC与HTTP/3
|
7天前
|
JSON API 数据处理
【Swift开发专栏】Swift中的RESTful API集成实战
【4月更文挑战第30天】本文探讨了在Swift中集成RESTful API的方法,涉及RESTful API的基础概念,如HTTP方法和设计原则,以及Swift的网络请求技术,如`URLSession`、`Alamofire`和`SwiftyJSON`。此外,还强调了数据处理、错误管理和异步操作的重要性。通过合理利用这些工具和策略,开发者能实现高效、稳定的API集成,提升应用性能和用户体验。
|
1天前
|
JSON 测试技术 API
pyhttptest 与 RESTful API 测试的完全指南
现在,无论是开发还是使用服务,我们每个人都面临着 REST API 的挑战。同时,我们正处于微服务的流行时代,我们将业务逻辑拆分为多个独立的小服务。这些服务大多遵循 RESTful 原则,并使用 JSON 格式进行通信,因为其简单性使其成为最广泛使用的格式。
|
1天前
|
缓存 测试技术 API
构建高效可扩展的RESTful API:后端开发的实践指南
【5月更文挑战第21天】 在现代Web开发领域,构建一个高效、可扩展且易于维护的RESTful API是至关重要的任务。本文将深入探讨如何利用最佳实践和先进技术栈来设计和实现一个健壮的后端服务。我们将讨论API设计原则、数据库优化策略、缓存机制、负载均衡以及容器化部署等方面,旨在为后端开发者提供一套全面的指导方案。
|
2天前
|
缓存 API 数据库
构建高效Python Web应用:Flask框架与RESTful API设计原则
【5月更文挑战第20天】 在现代Web开发中,构建一个轻量级且高效的后端服务至关重要。本文将深入探讨如何使用Python的Flask框架结合RESTful API设计原则来创建可扩展和易于维护的Web应用程序。我们将通过分析Flask的核心特性,以及如何利用它来实现资源的合理划分、接口的版本控制和请求处理优化等,来指导读者打造高性能的API服务。文中不仅提供了理论指导,还包括了实践案例,旨在帮助开发者提升开发效率,并增强应用的稳定性和用户体验。
|
2天前
|
Web App开发 存储 开发框架
使用Node.js构建RESTful API
【5月更文挑战第20天】本文指导使用Node.js和Express构建RESTful API。首先确保安装了Node.js,然后初始化项目,安装Express框架。在`app.js`中创建API,定义GET路由`/api/users`返回用户列表。运行服务器并测试API,最后讨论如何扩展API和提升其功能。这是一个构建RESTful API的基础入门教程。
|
7天前
|
存储 缓存 监控
利用Python和Flask构建RESTful API的实战指南
在当今的软件开发中,RESTful API已成为前后端分离架构中的核心组件。本文将带你走进实战,通过Python的Flask框架,一步步构建出高效、安全的RESTful API。我们将从项目初始化、路由设置、数据验证、错误处理到API文档生成,全方位地探讨如何构建RESTful API,并给出一些实用的最佳实践和优化建议。
|
7天前
|
存储 缓存 API
构建高效的RESTful API:后端开发的实践指南
【5月更文挑战第14天】 在现代Web开发领域,构建可靠且易于维护的后端服务至关重要。本文将详细探讨如何通过最佳实践和常用技术栈来构建一个高效的RESTful API。我们将涵盖API设计原则、数据库交互优化、缓存策略、安全性考虑以及性能监控等关键方面。通过本文的指导,读者将能够理解并实现一个符合工业标准且响应迅速的后端系统。
|
7天前
|
缓存 测试技术 API
RESTful API的最佳实践
【5月更文挑战第11天】在Python中构建RESTful API时,可以选择轻量级的Flask或全栈的Django框架。Flask适用于小型到中型API,而Django适合大型复杂项目。示例代码展示了如何在两个框架中创建任务列表API。
19 0
|
7天前
|
存储 缓存 JavaScript
深入理解RESTful API设计原则与实践
【5月更文挑战第7天】在现代Web服务开发中,表述性状态传递(REST)是一种广泛采用的架构风格,用于构建可扩展的网络应用程序接口(APIs)。本文将探讨RESTful API的核心设计原则,并通过具体实例展示如何实现一个符合REST约束的后端服务。我们将讨论资源的识别、客户端-服务器通信模式、无状态性、以及统一接口的重要性,并探索如何使用当前的流行技术栈来实现这些概念。