前言

  在以前,一个网站的完成总是“all in one”,页面,数据,渲染全部在服务端完成,这样做的最大的弊端是后期维护,扩展极其痛苦,开发人员必须同时具备前后端知识。于是慢慢的后来兴起了前后端分离的思想:

  后端负责数据编造,而前端则负责数据渲染,前端静态页面调用指定api获取到有固定格式的数据,再将数据展示出来,这样呈现给用户的就是一个”动态“的过程,而关于api这部分的设计则成了一个问题。如何设计出一个便于理解,容易使用的api则成了一个问题。

  而所谓的restful就是用来规范我们的api的一种约束。

  介绍

  rest是REpresentational State Transfer三个单词的缩写,由Roy Fielding于2000年论文中提出,它代表着分布式服务的架构风格。而如果想你的api被称为restful api,只要遵循其规定的约束即可。

  rest设计原则

  客户端-服务器:通过将用户UI与数据存储分开,我们可以简化服务器组件来提高跨多个平台的用户界面的可移植性并提高可伸缩性。 它可以比表现成前后端分离的思想。

  无状态:从客户端到服务器的每个请求都必须包含理解请求所需的所有信息,并且不能利用服务器上任何存储的上下文。 这表示你应该尽可能的避免使用session,由客户端自己标识会话状态。(token)

  规范接口:REST接口约束定义:资源识别; 请求动作; 响应信息; 它表示通过uri标出你要操作的资源,通过请求动作(http method)标识要执行的操作,通过返回的状态码来表示这次请求的执行结果。

  可缓存: 缓存约束要求将对请求的响应中的数据隐式或显式标记为可缓存或不可缓存。如果响应是可缓存的,则客户端缓存有权重用该响应数据以用于以后的等效请求。 它表示get请求响应头中应该表示有是否可缓存的头(Cache-Control)

  其中1,2,3约束最为重要,其中1容易理解。接下来我们就谈谈无状态和规范接口的原则。

  uri规范

  资源的描述构成了uri,它一般有以下约束:

  使用名词。如 user, student, class

  http://api.example.com/class-management/students

  http://api.example.com/device-management/managed-devices/{device-id}

  http://api.example.com/user-management/users/

  http://api.example.com/user-management/users/{id}

  http method对应不同的请求动作(数据库或者业务逻辑)

  GET:查询操作:

  HTTP GET /devices?startIndex=0size=20

  HTTP GET /configurations?startIndex=0size=20

  HTTP GET /devices/{id}/configurations

  HTTP GET /devices/{id}

  POST:新增操作:

  HTTP POST /device

  PUT 更新操作(代表更新一个实体的所有属性)

  HTTP PUT /devices/{id}

  PATCH 部分更新(代表更新一个尸体的部分属性)由于有的浏览器兼容性问题,一般推荐使用put

  HTTP PATCH /devices/{id}

  DELETE 删除操作

  HTTP DELETE /devices/{id}

  使用连字符( - )而不是(_)来提高URI的可读性

  http://api.example.com/inventory-management/managed-entities/{id}/install-script-location //更易读

  http://api.example.com/inventory_management/managed_entities/{id}/install_script_location //更容易出错

  在URI中使用小写字母

  http://api.example.org/my-folder/my-doc

  不要使用文件扩展名 文件扩展名看起来很糟糕,不会增加任何优势。删除它们也会减少URI的长度。没理由保留它们。

  http://api.example.com/device-management/managed-devices.xml / 不要使用它 /

  http://api.example.com/device-management/managed-devices / *这是正确的URI * /

  使用查询组件过滤URI集合

  很多时候,我们会遇到需要根据某些特定资源属性对需要排序,过滤或限制的资源集合的要求。为此,请不要创建新的API - 而是在资源集合API中启用排序,过滤和分页功能,并将输入参数作为查询参数传递。例如

  http://api.example.com/device-management/managed-devices

  http://api.example.com/device-management/managed-devices?region=USA

  http://api.example.com/device-management/managed-devices?region=USAbrand=XYZ

  http://api.example.com/device-management/managed-devices?region=USAbrand=XYZsort=installation-date

  不要在末尾使用/

  作为URI路径中的最后一个字符,正斜杠(/)不会添加语义值,并可能导致混淆。最好完全放弃它们。

  使用http状态码定义api执行结果

  1xx:信息

  通信传输协议级信息。

  2xx:成功

  表示客户端的请求已成功接受。

  3xx:重定向

  表示客户端必须执行一些其他操作才能完成其请求。

  4xx:客户端错误

  此类错误状态代码指向客户端。

  5xx:服务器错误

  服务器负责这些错误状态代码。

  另外完整的更为详细的状态码此处不做赘述。一般简化版本的api会使用200,400,500,其中400代表客户端调用有误,将错误信息放入response:

  {

  error: username.or.password.error

  }

  api版本定义

  当我们需要对现有的api接口升级的时候,因为该api接口已经投入使用,所以新添加的业务可能无法保证兼容原来的逻辑,这个时候就需要新的接口,而这个接口一般表示对原来的接口的升级(不同版本),那版本怎么定义呢?

  URI版本控制(推荐)

  http://api.example.com/v1

  http://apiv1.example.com

  使用自定义请求标头进行版本控制

  Accept-version:v1

  Accept-version:v2

  使用Accept header 进行版本控制

  Accept:application / vnd.example.v1 + json

  Accept:application / vnd.example + json; version = 1.0

  无状态

  使REST API无状态有一些非常显着的优点:

  无状态通过将API部署到多个服务器,有助于将API扩展到数百万并发用户。任何服务器都可以处理任何请求,因为没有与会话相关的依赖。(集群)

  无状态使得REST API不那么复杂 - 可以删除所有服务器端状态同步逻辑。(删除session,清理多余空间)

  无状态API也很容易缓存。特定软件可以通过查看该一个请求来决定是否缓存HTTP请求的结果。从先前的请求中获得的状态可能会影响这个请求的可缓存性,这并不存在任何不确定性。它提高了应用程序的性能。

  服务器永远不会忘记每个客户端身份”,因为客户端会在每个请求中发送所有必要的信息。(携带token)

  那么无状态又要怎么实现呢?前面我们已经说了,服务端不应该再保存session会话,这个工作全部交由http请求去标识,而最常见的做法则是使用token。生成token可以考虑使用jwt,oauth。其中jwt可以参考我的另一篇文章:https://www.jianshu.com/p/6ff0e30fc9e9

  总结

  我们首先介绍rest服务背景,引出rest架构的介绍,最后重点介绍了rest api的约束设计。

你真的了解restful api吗?的更多相关文章

  1. RESTful API URI 设计: 查询(Query)和标识(Identify)

    相关文章:RESTful API URI 设计的一些总结. 问题场景:删除一个资源(Resources),URI 该如何设计? 应用示例:删除名称为 iPhone 6 的产品. 是不是感觉很简单呢?根 ...

  2. 从英文变形规则计算到Restful Api设计

    ➠更多技术干货请戳:听云博客 一天在研究Restful API设计,命名的时候我总是很纠结,我相信大多数人也有这种感觉,不是说想不出来某个单词怎么写的问题,像我这种没事背单词背到13000词量的人也要 ...

  3. 好RESTful API的设计原则

    说在前面,这篇文章是无意中发现的,因为感觉写的很好,所以翻译了一下.由于英文水平有限,难免有出错的地方,请看官理解一下.翻译和校正文章花了我大约2周的业余时间,如有人愿意转载请注明出处,谢谢^_^ P ...

  4. RESTful API的设计原则

    好RESTful API的设计原则   说在前面,这篇文章是无意中发现的,因为感觉写的很好,所以翻译了一下.由于英文水平有限,难免有出错的地方,请看官理解一下.翻译和校正文章花了我大约2周的业余时间, ...

  5. Spring+SpringMVC+MyBatis+easyUI整合进阶篇(一)设计一套好的RESTful API

    写在前面的话 看了一下博客目录,距离上次更新这个系列的博文已经有两个多月,并不是因为不想继续写博客,由于中间这段时间更新了几篇其他系列的文章就暂时停止了,如今已经讲述的差不多,也就继续抽时间更新< ...

  6. 好的RESTful API的设计原则

    转载自一位大佬 英文原版 Principles of good RESTful API Design Good API design is hard! An API represents a cont ...

  7. 【API设计】RESTful API 设计指南

    RESTful API URL定位资源,用HTTP动词(GET,POST,DELETE,DETC)描述操作. 例如 . REST描述的是在网络中client和server的一种交互形式:REST本身不 ...

  8. REST与RESTFul API最佳实践

    我经常会面试一些做PHP的开发者,让我很奇怪的是,10个人总有8个多不知道什么是REST服务,甚至是没有听说过.但RESTFul API已经是现在互联网里对外开放接口的主流模式,可参考: 豆瓣API  ...

  9. 我所理解的Restful API最佳实践

    一直在公司负责API数据接口的开发,期间也遇到了不小的坑,本篇博客算是做一个小小的记录. 1. 不要纠结于无意义的规范    在开始本文之前,我想先说这么一句:RESTful 真的很好,但它只是一种软 ...

随机推荐

  1. git学习总结 - 纯命令

    全局安装git: npm intall git -g 查看git版本: git --version 进入目录,初始化git: 若在目录中使用上一个,不在目录中使用下一个. //已有目录: git in ...

  2. chrome platform

    folder_extension: ---menifest.json ---navigator_change.js manifest.json { "manifest_version&quo ...

  3. MySQL5.7 忘记root密码,怎么破?

    MySQL5.7 忘记root密码,怎么破? 关服 # kill $mysql_pid 免密启动 # /usr/local/mysql57/bin/mysqld_safe --defaults-fil ...

  4. 深入理解softmax函数

    Softmax回归模型,该模型是logistic回归模型在多分类问题上的推广,在多分类问题中,类标签  可以取两个以上的值.Softmax模型可以用来给不同的对象分配概率.即使在之后,我们训练更加精细 ...

  5. 简单了解一下php的迭代生成器yield

    yield是从PHP5.5开始有的,关于yidle的说明鸟哥的博客做了详细说明,我觉得是有点复杂,在看了几篇其他的帖子还有案例,我大概知道yield的作用就是在做大量数据循环处理的时候,能节省很大一部 ...

  6. 第一个django项目-通过命令行和pycharm两种方式

    以本机环境为例,ip地址为172.20.16.148,windows平台,虚拟环境路径为d:\VirtualEnv,项目存放位置为d:\DjangoProject 命令行方式 1.进入虚拟环境创建项目 ...

  7. fjwc2019 D2T2 定价 (栈+set+贪心)

    #182. 「2019冬令营提高组」定价 先瞄下数据范围 对于所有数据,1≤n≤1000,1≤m≤10^9,1≤q≤500000 .\textbf{2 操作的个数不超过 1000.} $10^9$位, ...

  8. Python3 tkinter基础 Frame bind 敲击键盘事件 将按键打印到console中

             Python : 3.7.0          OS : Ubuntu 18.04.1 LTS         IDE : PyCharm 2018.2.4       Conda ...

  9. Android 系统(64)---Android中m、mm、mmm、mma、mmma的区别【转】

    本文转载自:https://blog.csdn.net/zhangbijun1230/article/details/80196379 Android中m.mm.mmm.mma.mmma的区别   m ...

  10. LuoguP2680 运输计划

    题目地址 题目链接 题解 二分答案,那么大于答案的路径都需要有一条公共边,maxlen-val>=二分出来的x.val是边权. 考虑树剖,对每条大于答案的路径都+1(线段树里),枚举边,如果(线 ...