前言

移动互联网时代,RESTful API成为越来越重要的移动端和服务器端交互的形式。尤其是在很多互联网公司或者传统行业拥抱移动互联网的时候,一套设计良好的Restful API能够帮助互联网产品支持单服务端+多客户端的场景。RESTful架构本身是一个风格而不是一个标准,这也就意味着在具体设计时会有不同的实现。那么什么是好的RESTful
API呢?笔者认为适合的是最好的,能够根据本身产品的业务场景和阶段设计出结构清晰,易于理解,扩展方便的Restful API 就是最好的。

1、 什么是RESTful API

表征性状态传输(Representational State Transfer,简称REST )是Roy Fielding博士于2000年在他的博士论文中提出来的一种软件架构风格。如果一个架构符合REST原则,就称它为RESTful架构。说到Roy
Fielding几乎可以称之为HTTP协议之父,他是HTTP1.0和1.1的主要设计者,这篇基于HTTP协议的软件架构风格一出世就引起了关注并对互联网开发产生了深远的影响。发展到今日主流开源框架都提供了对REST的支持,大多数互联网公司都采用了RESTful架构。

2、 资源(Resources)是REST的核心

REST开发又被称作“面向资源的开发”,这说明对于资源的抽象是设计RESTful API的核心内容。RESTful API建模的过程与面向对象建模类似,是以名词为核心的。这些名词就是资源,任何可命名的抽象概念都可以定义为一个资源。对于业务的抽象是设计一套好的RESTful
API的基础,这就好比建房子打地基,如果地基没有打好,后面建的楼就很容易歪掉,其美观度,可维护性,可扩展性就会大大折扣。笔者会建议在设计初期一定要在资源的定义上多花功夫,抽象出适合业务发展的资源。也就是说一开始要把产品的RESTful风格定义下来,后面的扩展都可以基于这样的风格延续下去。

下面是几条小的建议:

-理清资源的层次结构,比如业务针对的范围是学校,那么学校会是一级资源(/school),老师(/school/teachers),学生(school/students)就是二级资源。

-资源尽量用准确的英文名词去表达,资源组都用复数来表达。一个好的资源定义一定是自解释的,也就是说你只需要很少的先验信息就能理解这个resource资源代表什么意思。

3、 资源的状态转化(State Transfer)

访问一个网站,代表的就是客户端和服务器的一个互动过程,这个过程中势必就涉及到数据和状态的变化。而广为使用的HTTP协议又恰恰是无状态的协议,这就意味这所有的状态都保存在服务器端。如果某个客户端想要操作服务器端必须通过某种手段让服务器发生状态转换。那么客户端可以操作的就是上文所定义的资源,而资源的状态转化就转化为对资源的各种操作。这些操作是通过HTTP协议的四种常用的方法来实现:GET,POST,PUT,DELETE。他们分别对应四种基本操作:GET-获取资源,POST-新建或者更新资源,PUT-更新资源,DELETE-删除资源。还有其它不常用的HTTP方法:PATCH/HEAD/OPTIONS方法。

对于HTTP方法的应用业界一直有两种声音:

-一种是尽量使用所有的HTTP方法去操作资源,请求里面只能带资源不能出现任何动词,如果发现资源上的操作过多以至于HTTP的方法不够用,应该考虑设计出更多的资源。这种方式适用于新产品的开发,产品是从建模开始的,可以充分的考虑各种业务场景定义出相应的资源。

-另一种是就是灵活适用,用GET去获取资源,其它涉及更改的操作都用POST,并当POST不能表达相应的动作时在URL中添加动词。比如在二手商品市场我发布了一个售卖手机的资源。那么对于这个资源,卖家本人可以对这个商品有取消的操作:POST /resources/123/cancel;买家可以对这个商品有购买的操作:POST
/resources/123/buy。这种方式适用于对现有非RESTful架构进行升级改造而修改模型影响更大的业务产品。当然这种选择也有可能是前后端程序猿们协商的结果,毕竟用一种最自然的沟通方式去架起前后端的桥梁才是目的所在。

4、 合理使用URL路径参数和请求

在URL路径里的参数一定是代表某个资源的ID,路径参数也可以是多个代表几级资源的IDs,例如获取一个老师所带班级的详情/teachers/#teacher_id/classes/#class_id。

对于HTTP GET,请求参数一般是作为可选参数获取某个资源列表的子集,例如获取年青老师的列表/teachers?group=young。

对于HTTP POST,请求参数是在消息体里,代表需要新建或者更新的资源。

5、 合理使用HTTP响应代码

HTTP响应状态代码,是HTTP协议这个统一接口中用来表达出错情况的标准机制。响应状态代码分成两部分:状态码和原因。两部分都是可定制的,也可以使用标准的状态码,只定制出错原因。在实际应用中也是两种选择:

•一种是对于应用出错的情况扩展状态码,定制出错原因。

•一种是对于容器处理的出错情况默认使用容器返回的错误码,例如tomcat容器返回的503,404;而对于应用本身返回的状态码一律返回200,对于应用出错码和原因都反应在返回消息体中。

6、 定义一套标准的返回体数据结构

对于所有的RESTful HTTP请求定义一套标准的返回结构体,前端可以根据这样的固定格式做标准化的解析,对于系统的可维护性起到很大的帮助。这个结构体里应该包含返回的具体资源,结果状态码和错误原因(如果有的话)。对于返回的资源,数据类型也尽量做到统一,比如日期,枚举类型都返回统一的数据类型避免不同的API对同一种数据有不同的处理方式。资源属性尽量做到可读也能大大减少前后端的沟通成本。

7、 RESTful API的版本控制

一个简单的做法是直接在URL中插入版本号,这样可以允许多个版本的API同时运行。在已经发布的版本中尽量做到向后兼容,包括URL和参数,对于返回值也是尽量增加新的冗余参数以兼容不同客户端不同的升级频率。等到所有的客户端升级以后再去除冗余的过程。

8、 RESTful API的安全性

安全性也是一个很大的话题,如果展开来讲又将是另外一篇文章。简单来讲主要是要考虑下面几个方面:

-对客户端做身份认证

-保证每个用户只能操作自己的资源,而不会CRUD属于别人的资源

-对于敏感数据做加密防止串改

-对于POST请求添加幂等机制以保证对资源的增加或者修改是安全的。

结语

最后作为结束语,想说明的是一套设计良好的RESTful一定是前后端反复沟通协商并不断迭代的过程。因为RESTful API作为前后端的桥梁我们需要同时考虑前后端的需求并达成一致的一个结果,桥梁之所以成为桥梁一定是双方都认可的沟通方式。架构是一门科学,也是一种艺术。

App后台开发运维和架构实践学习总结(2)——RESTful API设计技巧的更多相关文章

  1. App后台开发运维和架构实践学习总结(3)——RestFul架构下API接口设计注意点

    1. 争取相容性和统一性 这里就要求让API设计得是可预测的.按照这种方式写出所有接口和接口所需要的参数.现在就要确保命名是一致的,接口所需的参数顺序也是一致的.你现在应该有products,orde ...

  2. App后台开发运维和架构实践学习总结(5)——App产品从需求到研发到开发到上线到产品迭代全过程

    前言 如果没有做过开发,研发过产品的人,很难体会做产品的艰难,刚进公司的人,一般充当的是程序开发,我这里说的是开发,它与研发是有区别的. 一个需求下来,如果不能很好地理解产品需求,如果不能很好的驾驭需 ...

  3. App后台开发运维和架构实践学习总结(4)——APP的注册和登录功能设计

    一.为什么需要注册和登录? 是否需要注册和登录的关键取决于产品形态. 如果用户注册登录对于用户需求.产品功能.商业模式本身带不来任何价值的话,就没必要设计这样的功能.比如一些实用工具类的产品:计算器. ...

  4. App后台开发运维和架构实践学习总结(1)——App后台核心技术之用户验证方案

    对于初学者来说,对Token和Session的使用难免会限于困境,开发过程中知道有这个东西,但却不知道为什么要用他?更不知道其原理,今天我就带大家一起分析分析这东西. 一.使用Token进行身份鉴权 ...

  5. 《App后台开发运维与架构实践》第2章 App后台基础技术

    2.1 從App業務邏輯中提煉API接口 業務邏輯思維導圖 功能-業務邏輯思維導圖 基本功能模塊關系 功能模塊接口UML(設計出API) 在設計稿標注API 編寫API文檔 2.2 設計API的要點 ...

  6. 理解RESTful架构——Restful API设计指南

    理解RESTful架构 Restful API设计指南 理解RESTful架构 越来越多的人开始意识到,网站即软件,而且是一种新型的软件. 这种"互联网软件"采用客户端/服务器模式 ...

  7. 理解restful 架构 && RESTful API设计指南

    restful是前端和后端接口中都会使用的设计思想. 网站即软件,我们也常说的webapp,这种互联网软件采用的是“客户端/服务器”模式,建立在分布式体系上. 网站开发,也可以完全采用软件开发的模式, ...

  8. 移动互联网实战--Web Restful API设计和基础架构

    前言: 在移动互联网的大潮中, Web Restful API逐渐成为Web Server重要的一个分支. 移动端和服务端的交互, 主流的方式还是通过Http协议的形式来进行. 请求以Get/Post ...

  9. ****RESTful API 设计最佳实践(APP后端API设计参考典范)

    http://blog.jobbole.com/41233/ 背景 目前互联网上充斥着大量的关于RESTful API(为方便,下文中“RESTful API ”简写为“API”)如何设计的文章,然而 ...

随机推荐

  1. Magnetic Storms

    http://acm.timus.ru/problem.aspx?space=1&num=1126 简单的线段树求区间最值 #include <stdio.h> #include ...

  2. Paratroopers(最小割模型)

    http://poj.org/problem?id=3308 题意:一个m*n的网格,有L位火星空降兵降落在网格中,地球卫士为了能同时消灭他们,在网格的行或列安装了一个枪支,每行或每列的枪支都能消灭这 ...

  3. Going Home(MCMF)

    http://poj.org/problem?id=2195 题意:在一个n*m的图中,'m'代表人,'H'代表房子,人每移动一次的费用为1,求所有人移动到房子里的最小花费. 思路:最小费用最大流问题 ...

  4. codevs2557张程易(背包dp)

    2557 张程易,编程易  时间限制: 2 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond 题目描述 Description 张程易是一名神奇的魔法少女,在oier之中有着 ...

  5. quill支持json吗

    RT quill目前的驱动(2.4.2版本)不支持json,等待作者更新版本吧

  6. jdk1.8 api 下载

    链接: https://pan.baidu.com/s/1Wmf2vzXxclVcBPUfPp_g_A 提取码: dpwu 希望那些CSDN的不要借此収积分,行行好吧你,小众程序员就是为了方便 凑字数 ...

  7. hdu2029

    http://acm.hdu.edu.cn/showproblem.php?pid=2029 #include<stdio.h> #include<string.h> #inc ...

  8. Android 图片异步加载 加载网络图片

    最近用到了加载网络图片,研究了一下,写一点简单的介绍: 首先创建一个线程去取图片(网络请求必须放在线程中): /** * 使用继承java.lang.Thread类的方式创建一个线程 * 直接取图片, ...

  9. 343 Integer Break 整数拆分

    给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化. 返回你可以获得的最大乘积.例如,给定 n = 2,返回1(2 = 1 + 1):给定 n = 10,返回36(10 = 3 ...

  10. c的二级指针

    ----"c 语言的精华在于指针的灵活性.学好指针的目的在于尽可能少的使用指针." 在敲binary search tree(二叉查找树),遇到了问题.在删除的时候,如果删除的是r ...