RESTful设计中的常见疑问

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

1.什么是RESTful

详情能够看http://www.ruanyifeng.com/blog/2011/09/restful.html前端

简单能够这么理解,使用URI去表明资源,使用HTTP VERB(GET PUT等)对资源的操做。git

2.为何要用RESTful

使用RESTful,优势有不少,也方便不一样的请求方去请求数据。列举两个:github

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

那是否是每个API都须要使用REST风格呢?我以为不是,这要看团队、项目而定,没必要一味强求。json

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

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

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相似的功能。restful

有一些现成的库能够帮助咱们实现上面的Versioning方法,常见的是aspnet-api-versioningpost

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之类的方法去大致肯定返回的状态 。

相关文章
相关标签/搜索