最近写了几个有关RESTful的API相关内容,也谈谈对常见问题的自己的理解。

1.什么是RESTful

详情可以看http://www.ruanyifeng.com/blog/2011/09/restful.html

简单可以这么理解,使用URI去代表资源,使用HTTP VERB(GET PUT等)对资源的操作。

2.为什么要用RESTful

使用RESTful,优点有很多,也方便不同的请求方去请求数据。列举两个:

  • HTTP方法语义都很明确,使用GET去获得数据,使用DELETE去删除数据。
  • 返回值也是很明确的HTTP RESPONSE,200就是执行成功,400就是请求错误。

那是不是每一个API都需要使用REST风格呢?我觉得不是,这要看团队、项目而定,不必一味强求。

3.在URI资源地址中使用v1之类的版本号符不符合RESTful?

这个涉及到RESTful的版本管理,常见的方法有这么几种。

URL Path

/api/v1/helloworld

很多公开的API地址里面,都带有version信息,如果非要去扣符不符合RESTful,估计要吵起来。但是这个方式很便捷、明确,调用方一看就明白,也没有额外的工作量去做。不过缺点也很明显,由于已经限定死了版本号在URI中,无法实现同一个URI地址版本的灵活切换,也不能指定默认版本。

Query String

/api/helloworld?api-version=1.0

这个方式没有改变URI本身,但是需要调用方去额外处理Query string,不过好在这个可以指定默认的。

Media Types

POST api/helloworld HTTP/1.1
host: localhost
content-type: text/plain;v=2.0
content-length: 12 Hello there!

在Content-Type里面添加v=x.x的版本号也是一个不错的选择,可以实现QueryString类似的功能。

有一些现成的库可以帮助我们实现上面的Versioning方法,常见的是aspnet-api-versioning

4.什么是安全性?

无论请求多少次,服务器的状态(资源)都不会改变,那么这个方法就是安全的。

GET HEAD都应该设计成安全的。

5.什么是幂等性?

无论对资源操作多少次,服务器资源结果总是一样的,那么这个方法就是幂等的。注意这里的说法,是服务器的资源结果是一样的,不代表请求的返回结果是一样的。比如DELETE请求,它是幂等的,但是删除一个资源很多次的情况(多次执行DELETE api/student/1,第一次返回成功,第二次返回失败,但是不影响服务器上对应的记录已经删除的状态。

GET、HEAD、PUT和DELETE请求都应该设计成是幂等的。

6.新增数据用POST还是PUT?

资源新增可以用POST也可以用PUT,但是设计上有几个区别。

幂等性

PUT是幂等的,POST不是,如果设计上需要不应用幂等性,那么使用POST。比如POST计数器的应用,每次POST,计数器都增长1。

请求目标

POST一般请求的是资源集合,而PUT一般请求是一个具体的资源。

PUT /students/{id}
POST /students

这也意味着,语义上,POST是请求在集合中新增资源。

主动权

  • 如果id不是由调用方生成的情况下,需要指定的资源ID的PUT方法就不好实现了。这种情况,使用POST到资源更合理,主动权在服务器方,服务器创建资源之后,返回201携带新生成的对象URI。
  • 如果id是由调用方生成的情况下(比如一些硬件设备产生的数据),使用POST和PUT都可以,但是PUT有幂等性,显得更加明确,这种时候我一般选择使用PUT。

覆盖

PUT语义是要求覆盖的,如果数据已经存在,就必须覆盖。POST的没有这个要求,可以有别的行为。

7.修改数据应该使用PUT还是PATCH?

不一定,要看情况。PUT是覆盖性的修改,而PATCH是追加性的修改。

  • 使用PUT的时候,需要将数据完整返回,如果有的字段没有赋值,那么将保持为默认值。
  • PUT是幂等的,PATCH不是,因此多次执行PUT请求,结果是一样的;执行PATCH有可能不一样。
{
"value":
{
"id": "235314",
"deviceId": "123",
"type": "低温"
}
}

如果发送的数据只含有deviceId,执行PUT之后,资源变成:

{
"value":
{
"id": "235314",
"deviceId": "111"
}
}

执行PATCH,资源变成:

{
"value":
{
"id": "235314",
"deviceId": "111",
"type": "低温"
}
}

8.没有数据返回204还是404?

问题:

如果请求一个这样的资源

GET api/sutudents/homework

在没有homework的情况下应该返回HTTP 204 NoContent还是返回HTTP 404 NotFound?

乍看一眼,觉得好像都差不多,没内容和没找到反正都是没有。但深入想想,还是有很大的区别的。

  1. 404返回的更倾向于表述不存在的性质,而204返回表述没有内容,也就是存在,但是没有内容。
  2. 4xx返回表述大体是请求有问题,而2xx返回表述大体是请求没有问题。

所以,对于上面的问题,这么理解,如果homework是已经创建的资源,但是内容为空,那么返回204是可以的,但是如果homework这个东西就不存在,那么应该返回404。

个人认为直接返回200,携带对应的空内容会比204要对调用方更加友好,至少和有数据的情况是一样处理。

9.写给前端

有很多前端同学需要服务器返回固定的成功信息(比如200)或者错误信息(比如400)。但HTTP CODE很多,一个一个判断效率很低,好在HTTP CODE是分类的,比如2xx大体是OK的,4xx都是有问题的。可以通过CODE / 100 == 2之类的方法去大体确定返回的状态 。

RESTful设计中的常见疑问的更多相关文章

  1. 教你避雷!网页设计中常见的17个UI设计错误集锦(附赠设计技巧)

    以下内容由摹客团队翻译整理,仅供学习交流,摹客iDoc是支持智能标注和切图的产品协作设计神器. 精心设计的用户界面对网站意义重大.具备所有最新功能和响应式设计有助于提高网站的搜索引擎排名,从而增加受众 ...

  2. AI技术在智能海报设计中的应用

    背景 在视觉设计领域中,设计师们往往会因为一些简单需求付出相当多的时间,比如修改文案内容,设计简单的海报版式,针对不同机型.展位的多尺寸拓展等.这些工作需要耗费大量的时间.人力成本(5~6张/人日), ...

  3. 使用Axure设计中,大型的后台系统原型总结

    使用Axure设计中,大型的后台系统原型总结 2018年4月16日luodonggan 在产品原型设计中,经常会涉及到后台系统原型的设计,如何设计出更规范标准的后台系统原型,是很多产品同行们都会遇到的 ...

  4. RESTful 设计理论

    RESTful 设计: 1.协议通信协议:https 2.域名部署在API专用域名下,除非API很简单(https://www.example.com/api)https://api.example. ...

  5. Java Web学习(八)RESTful设计

    一.RESTful设计风格 REST :指的是一组架构约束条件和原则. RESTful :满足这些约束条件和原则的应用程序或设计就是 . REST 原则 客户端和服务器之间的交互在请求之间是无状态的. ...

  6. Net中的常见的关键字

    Net中的关键字有很多,我们最常见的就有new.base.this.using.class.struct.abstract.interface.is.as等等.有很多的,在这里就介绍大家常见的,并且有 ...

  7. 浅谈UI设计中妙用无穷的深色系背景

    英文:medium 译者:优设网 - 陈子木 链接:http://www.uisdc.com/ui-benefits-of-dark-background# --------------------- ...

  8. 网页设计中常用的19个Web安全字体

    来自http://www.jb51.net 在Web编码中,CSS默认应用的Web字体是有限的,虽然在新版本的CSS3,我们可以通过新增的@font-face属性来引入特殊的浏览器加载字体.但多数情况 ...

  9. 内存中 OLTP - 常见的工作负荷模式和迁移注意事项(三)

    ----------------------------我是分割线------------------------------- 本文翻译自微软白皮书<In-Memory OLTP – Comm ...

随机推荐

  1. javascript实例教程使用canvas技术模仿echarts柱状图

    canvas 画布是HTML5中新增的标签,可以通过js操作 canvas 绘图 API在网页中绘制图像. 百度开发了一个开源的可视化图表库ECharts,功能非常强大,可以实现折线图.柱状图.散点图 ...

  2. 一个可能是世界上最全的 API 接口集合库开源项目

    对于程序员来说,为自己的程序选择一些合适的API并不是那么简单,有时候还会把你搞得够呛,今天猿妹要和大家分享一个开源项目,这个项目汇集了各种开发的api,涵盖了音乐.新闻.书籍.日历等,无论你是从事W ...

  3. Python基础之语言简介

    python是什么 Python 是一个高层次的结合了解释性.编译性.互动性和面向对象的脚本语言,其设计具有很强的可读性,相比其他语言经常使用英文关键字,其他语言的一些标点符号,它具有比其他语言更有特 ...

  4. tensorflow1.0 模型的保存与加载

    import tensorflow as tf import numpy as np # ##Save to file # W = tf.Variable([[4,5,6],[7,8,9]],dtyp ...

  5. 使用sqlmap结合dnslog快速注入

    0x01 起因 实际项目中遇到一个oracle延时注入,需要获取数据,几十个库几百张表,等找到关键数据不知道要到哪天. 测试支持带外请求 于是想用使用sqlmap利用DNS进行OOB注入 0x02 阿 ...

  6. 以命令行界面启动 Ubuntu

    1. /etc/default/grub 将GRUB_CMDLINE_LINUX_DEFAULT一行中改为"quiet splash 3" 2. update-grub 3. 重启

  7. 通过注册表查询 .Net Framework 的版本

    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full 注意:即使卸载 .Net Framework 这些注册表依然 ...

  8. 咦,Java拆分个字符串都这么讲究

    提到 Java 拆分字符串,我猜你十有八九会撂下一句狠话,"这有什么难的,直接上 String 类的 split() 方法不就拉到了!"假如你真的这么觉得,那可要注意了,事情远没这 ...

  9. KVM 一键批量创建虚拟机

    目录 一.原理 二.基础镜像 2.1.创建基础镜像 2.2. 完善基础镜像 2.3.基础镜像设置权限 3.4 设置 title 3.5.基础镜像XML 三.批量创建机器脚本 四.挂载磁盘多种方式 4. ...

  10. 单源最短路问题--朴素Dijkstra & 堆优化Dijkstra

    许久没有写博客,更新一下~ Dijkstra两种典型写法 1. 朴素Dijkstra     时间复杂度O(N^2)       适用:稠密图(点较少,分布密集) #include <cstdi ...