你真的了解restful api吗?

restful api

本文原创地址,我的博客https://jsbintask.cn/2019/03/20/api/restful-api-best-practices/(食用效果最佳),转载请注明出处!

前言

在以前,一个网站的完成总是“all in one”,页面,数据,渲染全部在服务端完成,这样做的最大的弊端是后期维护,扩展极其痛苦,开发人员必须同时具备前后端知识。于是慢慢的后来兴起了前后端分离的思想:
后端负责数据编造,而前端则负责数据渲染,前端静态页面调用指定api获取到有固定格式的数据,再将数据展示出来,这样呈现给用户的就是一个”动态“的过程,而关于api这部分的设计则成了一个问题。如何设计出一个便于理解,容易使用的api则成了一个问题。
而所谓的restful就是用来规范我们的api的一种约束。

介绍

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

rest设计原则

  1. 客户端-服务器:通过将用户UI与数据存储分开,我们可以简化服务器组件来提高跨多个平台的用户界面的可移植性并提高可伸缩性。 它可以比表现成前后端分离的思想。
  2. 无状态:从客户端到服务器的每个请求都必须包含理解请求所需的所有信息,并且不能利用服务器上任何存储的上下文。 这表示你应该尽可能的避免使用session,由客户端自己标识会话状态。(token)
  3. 规范接口:REST接口约束定义:资源识别; 请求动作; 响应信息; 它表示通过uri标出你要操作的资源,通过请求动作(http method)标识要执行的操作,通过返回的状态码来表示这次请求的执行结果。
  4. 可缓存: 缓存约束要求将对请求的响应中的数据隐式或显式标记为可缓存或不可缓存。如果响应是可缓存的,则客户端缓存有权重用该响应数据以用于以后的等效请求。 它表示get请求响应头中应该表示有是否可缓存的头(Cache-Control)
    其中1,2,3约束最为重要,其中1容易理解。接下来我们就谈谈无状态和规范接口的原则。

uri规范

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

  1. 使用名词。如 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}

  2. http method对应不同的请求动作(数据库或者业务逻辑)
    GET:查询操作:
    HTTP GET /devices?startIndex=0&size=20
    HTTP GET /configurations?startIndex=0&size=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}

  3. 使用连字符( - )而不是(_)来提高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 //更容易出错

  4. 在URI中使用小写字母
    http://api.example.org/my-folder/my-doc

  5. 不要使用文件扩展名 文件扩展名看起来很糟糕,不会增加任何优势。删除它们也会减少URI的长度。没理由保留它们。
    http://api.example.com/device-management/managed-devices.xml / 不要使用它 /
    http://api.example.com/device-management/managed-devices / *这是正确的URI * /

  6. 使用查询组件过滤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=USA&brand=XYZ
    http://api.example.com/device-management/managed-devices?region=USA&brand=XYZ&sort=installation-date

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

  8. 使用http状态码定义api执行结果
    1xx:信息
    通信传输协议级信息。

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

3xx:重定向
表示客户端必须执行一些其他操作才能完成其请求。

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

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

{
  "error": "username.or.password.error"
}
  1. 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无状态有一些非常显着的优点:

  1. 无状态通过将API部署到多个服务器,有助于将API扩展到数百万并发用户。任何服务器都可以处理任何请求,因为没有与会话相关的依赖。(集群)
  2. 无状态使得REST API不那么复杂 - 可以删除所有服务器端状态同步逻辑。(删除session,清理多余空间)
  3. 无状态API也很容易缓存。特定软件可以通过查看该一个请求来决定是否缓存HTTP请求的结果。从先前的请求中获得的状态可能会影响这个请求的可缓存性,这并不存在任何不确定性。它提高了应用程序的性能。
  4. 服务器永远不会忘记每个客户端身份”,因为客户端会在每个请求中发送所有必要的信息。(携带token)

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

总结

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

关注我,这里只有干货!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容

  • TABLE OF CONTENTS Introduction 7 Overview of FortiCloud 7...
    Bouw阅读 2,292评论 0 0
  • API定义规范 本规范设计基于如下使用场景: 请求频率不是非常高:如果产品的使用周期内请求频率非常高,建议使用双通...
    有涯逐无涯阅读 2,442评论 0 6
  • 去年有段时间得空,就把谷歌GAE的API权威指南看了一遍,收获颇丰,特别是在自己几乎独立开发了公司的云数据中心之后...
    骑单车的勋爵阅读 20,132评论 0 41
  • mean to add the formatted="false" attribute?.[ 46% 47325/...
    ProZoom阅读 2,615评论 0 3
  • 人的一生会遇到两个人,一个温柔了岁月,一个惊艳了时光,那更重要的就是遇见,遇见是一件很美好的事情,我们每天都在期待...
    爱咬人的小仙女阅读 117评论 0 0