java 发表于 2019-4-19 18:58:27

RESTful

本帖最后由 java 于 2019-4-19 18:59 编辑

一.什么是RESTful 面向资源
简单的说:RESTful是一种架构的规范与约束、原则,符合这种规范的架构就是RESTful架构。

先看REST是什么意思,英文Representational state transfer 表述性状态转移 其实就是对 资源 的表述性状态转移。
(什么是表述性:就是指客户端请求一个资源,服务器拿到的这个资源,就是表述)
资源的地址 在web中就是URL (统一资源标识符)
资源是REST系统的核心概念。 所有的设计都是以资源为中心

结合项目怎么识别资源
1.商品加入购物车 购物车
2.提交订单 订单
3.创建用户 用户

围绕资源进行 添加,获取,修改,删除,以及对符合特定条件的资源进行列表操作 。针对资源设计接口
二.关于规范与约束有哪些?
RESTful 架构的核心规范与约束:统一接口
分为四个子约束:
1.每个资源都拥有一个资源标识,每个资源的资源标识可以用来唯一地标明该资源
2.消息的自描述性
3.资源的自描述性。
4.HATEOAS Hypermedia As The Engine Of Application State(超媒体作为应用状态引擎)
即客户只可以通过服务端所返回各结果中所包含的信息来得到下一步操作所需要的信息,如到底是向哪个URL发送请求等。也就是说,一个典型的REST服务不需要额外的文档标示通过哪些URL访问特定类型的资源,而是通过服务端返回的响应来标示到底能在该资源上执行什么样的操作

目的:实现客户端无需借助任何文档即能调用到所有的服务器资源


三、资源的URL设计
1.通过URL来表示资源
资源分为主资源与子资源
因为主资源是一类独立的资源 所以主资源应直接放在相对路径下:例如
若要表示主资源的实例:如果实例的ID=1,则这样表示: /goods/1
子资源:
一个实例的子资源可能是一个集合也可能是一个单一的子资源
子资源为图片集合:/goods/1/pictures
子资源为商品折扣的单子子资源:/goods/1/discount
2.单数 vs. 复数
获取用户1的信息,哪种方式更符合RESTful?
/api/users/1
/api/user/1
3.相对路径 vs. 请求参数
极光的RESTful API:
获取用户信息 GET /v1/users/{username} 参数放在路径中
VS
获取用户信息 GET /v1/users?username=xxxxx 拼接的方式

获取应用管理员列表 GET /v1/admins?start={start}&count={count} ?后拼接参数的方式:这种方式一般作为过滤资源


4.使用合适的动词 get delete put post

选择请求接口的方式: get delete
PUT 在服务器更新资源(客户端提供改变后的完整资源)。
POST 在服务器新建一个资源

5.使用标准的状态码

GET
[*]安全且幂等
[*]获取表示
[*]变更时获取表示(缓存)

[*]200(OK) - 表示已在响应中发出

[*]204(无内容) - 资源有空表示
[*]301(Moved Permanently) - 资源的URI已被更新
[*]303(See Other) - 其他(如,负载均衡)
[*]304(not modified)- 资源未更改(缓存)
[*]400 (bad request)- 指代坏请求(如,参数错误)
[*]404 (not found)- 资源不存在
[*]406 (not acceptable)- 服务端不支持所需表示
[*]500 (internal server error)- 通用错误响应
[*]503 (Service Unavailable)- 服务端当前无法处理请求
[*]POST

[*]不安全且不幂等
[*]使用服务端管理的(自动产生)的实例号创建资源
[*]创建子资源
[*]部分更新资源
[*]如果没有被修改,则不过更新资源(乐观锁)

[*]200(OK)- 如果现有资源已被更改

[*]201(created)- 如果新资源被创建
[*]202(accepted)- 已接受处理请求但尚未完成(异步处理)
[*]301(Moved Permanently)- 资源的URI被更新
[*]303(See Other)- 其他(如,负载均衡)
[*]400(bad request)- 指代坏请求
[*]404 (not found)- 资源不存在
[*]406 (not acceptable)- 服务端不支持所需表示
[*]409 (conflict)- 通用冲突
[*]412 (Precondition Failed)- 前置条件失败(如执行条件更新时的冲突)
[*]415 (unsupported media type)- 接受到的表示不受支持
[*]500 (internal server error)- 通用错误响应
[*]503 (Service Unavailable)- 服务当前无法处理请求
PUT
[*]不安全但幂等
[*]用客户端管理的实例号创建一个资源
[*]通过替换的方式更新资源
[*]如果未被修改,则更新资源(乐观锁)

[*]200 (OK)- 如果已存在资源被更改

[*]201 (created)- 如果新资源被创建
[*]301(Moved Permanently)- 资源的URI已更改
[*]303 (See Other)- 其他(如,负载均衡)
[*]400 (bad request)- 指代坏请求
[*]404 (not found)- 资源不存在
[*]406 (not acceptable)- 服务端不支持所需表示
[*]409 (conflict)- 通用冲突
[*]412 (Precondition Failed)- 前置条件失败(如执行条件更新时的冲突)
[*]415 (unsupported media type)- 接受到的表示不受支持
[*]500 (internal server error)- 通用错误响应
[*]503 (Service Unavailable)- 服务当前无法处理请求
DELETE
[*]不安全但幂等
[*]删除资源

[*]200 (OK)- 资源已被删除

[*]301 (Moved Permanently)- 资源的URI已更改
[*]303 (See Other)- 其他,如负载均衡
[*]400 (bad request)- 指代坏请求
[*]404 (not found)- 资源不存在
[*]409 (conflict)- 通用冲突
[*]500 (internal server error)- 通用错误响应
[*]503 (Service Unavailable)- 服务端当前无法处理请求
[*]6.选择适当的表示结构
json   xml

7. 版本控制
例如:https://images2018.cnblogs.com/blog/1327924/201806/1327924-20180628134227185-490970060.png





hello world!!!

https://www.cnblogs.com/wang-yaz/p/9237981.html


java 发表于 2019-4-19 19:08:14

RESTful 是目前最流行的 API 设计规范,用于 Web 数据接口的设计。它的大原则容易把握,但是细节不容易做对。本文总结 RESTful 的设计细节,介绍如何设计出易于理解和使用的 API。https://www.wangbase.com/blogimg/asset/201810/bg2018100301.jpg一、URL 设计1.1 动词 + 宾语RESTful 的核心思想就是,客户端发出的数据操作指令都是"动词 + 宾语"的结构。比如,GET /articles这个命令,GET是动词,/articles是宾语。动词通常就是五种 HTTP 方法,对应 CRUD 操作。
[*]GET:读取(Read)
[*]POST:新建(Create)
[*]PUT:更新(Update)
[*]PATCH:更新(Update),通常是部分更新
[*]DELETE:删除(Delete)
根据 HTTP 规范,动词一律大写。1.2 动词的覆盖有些客户端只能使用GET和POST这两种方法。服务器必须接受POST模拟其他三个方法(PUT、PATCH、DELETE)。这时,客户端发出的 HTTP 请求,要加上X-HTTP-Method-Override属性,告诉服务器应该使用哪一个动词,覆盖POST方法。POST /api/Person/4 HTTP/1.1X-HTTP-Method-Override: PUT上面代码中,X-HTTP-Method-Override指定本次请求的方法是PUT,而不是POST。1.3 宾语必须是名词宾语就是 API 的 URL,是 HTTP 动词作用的对象。它应该是名词,不能是动词。比如,/articles这个 URL 就是正确的,而下面的 URL 不是名词,所以都是错误的。
[*]/getAllCars
[*]/createNewCar
[*]/deleteAllRedCars
1.4 复数 URL既然 URL 是名词,那么应该使用复数,还是单数?这没有统一的规定,但是常见的操作是读取一个集合,比如GET /articles(读取所有文章),这里明显应该是复数。为了统一起见,建议都使用复数 URL,比如GET /articles/2要好于GET /article/2。1.5 避免多级 URL常见的情况是,资源需要多级分类,因此很容易写出多级的 URL,比如获取某个作者的某一类文章。GET /authors/12/categories/2这种 URL 不利于扩展,语义也不明确,往往要想一会,才能明白含义。更好的做法是,除了第一级,其他级别都用查询字符串表达。GET /authors/12?categories=2下面是另一个例子,查询已发布的文章。你可能会设计成下面的 URL。GET /articles/published查询字符串的写法明显更好。GET /articles?published=true二、状态码2.1 状态码必须精确客户端的每一次请求,服务器都必须给出回应。回应包括 HTTP 状态码和数据两部分。HTTP 状态码就是一个三位数,分成五个类别。
[*]1xx:相关信息
[*]2xx:操作成功
[*]3xx:重定向
[*]4xx:客户端错误
[*]5xx:服务器错误
这五大类总共包含100多种状态码,覆盖了绝大部分可能遇到的情况。每一种状态码都有标准的(或者约定的)解释,客户端只需查看状态码,就可以判断出发生了什么情况,所以服务器应该返回尽可能精确的状态码。API 不需要1xx状态码,下面介绍其他四类状态码的精确含义。2.2 2xx 状态码200状态码表示操作成功,但是不同的方法可以返回更精确的状态码。
[*]GET: 200 OK
[*]POST: 201 Created
[*]PUT: 200 OK
[*]PATCH: 200 OK
[*]DELETE: 204 No Content
上面代码中,POST返回201状态码,表示生成了新的资源;DELETE返回204状态码,表示资源已经不存在。此外,202 Accepted状态码表示服务器已经收到请求,但还未进行处理,会在未来再处理,通常用于异步操作。下面是一个例子。HTTP/1.1 202 Accepted{"task": {    "href": "/api/company/job-management/jobs/2130040",    "id": "2130040"}}2.3 3xx 状态码API 用不到301状态码(永久重定向)和302状态码(暂时重定向,307也是这个含义),因为它们可以由应用级别返回,浏览器会直接跳转,API 级别可以不考虑这两种情况。API 用到的3xx状态码,主要是303 See Other,表示参考另一个 URL。它与302和307的含义一样,也是"暂时重定向",区别在于302和307用于GET请求,而303用于POST、PUT和DELETE请求。收到303以后,浏览器不会自动跳转,而会让用户自己决定下一步怎么办。下面是一个例子。HTTP/1.1 303 See OtherLocation: /api/orders/123452.4 4xx 状态码4xx状态码表示客户端错误,主要有下面几种。400 Bad Request:服务器不理解客户端的请求,未做任何处理。401 Unauthorized:用户未提供身份验证凭据,或者没有通过身份验证。403 Forbidden:用户通过了身份验证,但是不具有访问资源所需的权限。404 Not Found:所请求的资源不存在,或不可用。405 Method Not Allowed:用户已经通过身份验证,但是所用的 HTTP 方法不在他的权限之内。410 Gone:所请求的资源已从这个地址转移,不再可用。415 Unsupported Media Type:客户端要求的返回格式不支持。比如,API 只能返回 JSON 格式,但是客户端要求返回 XML 格式。422 Unprocessable Entity :客户端上传的附件无法处理,导致请求失败。429 Too Many Requests:客户端的请求次数超过限额。2.5 5xx 状态码5xx状态码表示服务端错误。一般来说,API 不会向用户透露服务器的详细信息,所以只要两个状态码就够了。500 Internal Server Error:客户端请求有效,服务器处理时发生了意外。503 Service Unavailable:服务器无法处理请求,一般用于网站维护状态。三、服务器回应3.1 不要返回纯本文API 返回的数据格式,不应该是纯文本,而应该是一个 JSON 对象,因为这样才能返回标准的结构化数据。所以,服务器回应的 HTTP 头的Content-Type属性要设为application/json。客户端请求时,也要明确告诉服务器,可以接受 JSON 格式,即请求的 HTTP 头的ACCEPT属性也要设成application/json。下面是一个例子。GET /orders/2 HTTP/1.1 Accept: application/json3.2 发生错误时,不要返回 200 状态码有一种不恰当的做法是,即使发生错误,也返回200状态码,把错误信息放在数据体里面,就像下面这样。HTTP/1.1 200 OKContent-Type: application/json{"status": "failure","data": {    "error": "Expected at least two items in list."}}上面代码中,解析数据体以后,才能得知操作失败。这张做法实际上取消了状态码,这是完全不可取的。正确的做法是,状态码反映发生的错误,具体的错误信息放在数据体里面返回。下面是一个例子。HTTP/1.1 400 Bad RequestContent-Type: application/json{"error": "Invalid payoad.","detail": {   "surname": "This field is required."}}3.3 提供链接API 的使用者未必知道,URL 是怎么设计的。一个解决方法就是,在回应中,给出相关链接,便于下一步操作。这样的话,用户只要记住一个 URL,就可以发现其他的 URL。这种方法叫做 HATEOAS。举例来说,GitHub 的 API 都在 api.github.com 这个域名。访问它,就可以得到其他 URL。{..."feeds_url": "https://api.github.com/feeds","followers_url": "https://api.github.com/user/followers","following_url": "https://api.github.com/user/following{/target}","gists_url": "https://api.github.com/gists{/gist_id}","hub_url": "https://api.github.com/hub",...}上面的回应中,挑一个 URL 访问,又可以得到别的 URL。对于用户来说,不需要记住 URL 设计,只要从 api.github.com 一步步查找就可以了。HATEOAS 的格式没有统一规定,上面例子中,GitHub 将它们与其他属性放在一起。更好的做法应该是,将相关链接与其他属性分开。HTTP/1.1 200 OKContent-Type: application/json{"status": "In progress",   "links": {[    { "rel":"cancel", "method": "delete", "href":"/api/status/12345" } ,    { "rel":"edit", "method": "put", "href":"/api/status/12345" }]}}四、参考链接
[*]RESTful API Design: 13 Best Practices to Make Your Users Happy, by Florimond Manca
[*]API design, by MicroSoft Azure
(完)
http://www.ruanyifeng.com/blog/2018/10/restful-api-best-practices.html

页: [1]
查看完整版本: RESTful