RESTful API学习笔记

现在的后端接口都是restful API模式较多,经常性的接触到这个词汇,今天就来仔细研究下它到底是什么意思把。

1.字面含义阐述:

REST:Representational State Transfer,翻译是”表述性资源状态转化

2.理解RESTful

要理解RESTful架构,就要去理解Representational State Transfer这个词组的含义。

下面我们结合REST原则,围绕资源展开讨论,从资源的定义、获取、表述、关联、状态变迁等角度,列举一些关键概念并加以解释。

  • 资源与URI
  • 统一资源接口
  • 资源的表述
  • 资源的链接
  • 状态的转移

    2.1 什么是表述性资源与URI?

    资源定义其实很宽泛,只要有被使用到的价值都可以叫做资源。比如说某个人的手机号码,或者说潜在的投资价值等。

    在Web上我们主要讲的资源就是各种能够得到的数据,图片等信息

    如何让一个资源可以得到标识,就像我们每个人的身份证号码一样,根据身份证号码就可以得到一个人的基本信息?

    在web上我们的标识就是URI(Uniform Resource Identifier)。URI既可以看成是资源的地址,也可以看成是资源的名称。

    URI的设计应该遵循可寻址性原则具有自描述性,需要在形式上给人以直觉上的关联。

    这里直接给出满足RESTful原则的url设计提倡:

    https://xxx.com/api/v1/actionName

    协议 / 网址 / 表示是api接口 / 接口版本 / 请求的api名字

    2.2 什么是统一资源接口?

    统一接口包含了一组受限的预定义的操作,不论什么样的资源,都是通过使用相同的接口进行资源的访问。简单来理解其实就是我们经常见到的HTTP方法:

    • GET(SELECT):从服务器取出资源(一项或多项)。
    • POST(CREATE):在服务器新建一个资源。
    • PUT(UPDATE):在服务器更新资源(客户端提供改变后的完整资源)。
    • PATCH(UPDATE):在服务器更新资源(客户端提供改变的属性)。
    • DELETE(DELETE):从服务器删除资源。

    我们通常都是使用get,post等方法进行请求接口。

    2.3 什么是资源的表述?

    资源的表述包括数据和描述数据的元数据,例如,HTTP头”Content-Type” 就是这样一个元数据属性。

    那么客户端如何知道服务端提供哪种表述形式呢?

    我们通常都是通过HTTP内容进行协商,客户端可以通过Accept头请求一种特定格式的表述,服务端则通过Content-Type告诉客户端资源的表述形式。

    
    # Request
    
    GET https://api.github.com/orgs/github HTTP/1.1
    Accept: application/json
    
    
    #Response
    
    HTTP/1.1 200 OK
    Content-Type:application/json;charset=utf-8
    
    {
        "login":"github",
        "id":"1",
        "url":"https://api.github.com/orgs/github",
        "name":"github"
        ...
    }
    2.4 什么是资源的链接?

    当我们浏览Web网页时,从一个链接跳到一个页面,再从另一个链接跳到另外一个页面,就是利用了超媒体的概念:把一个个把资源链接起来.

    要达到这个目的,就要求在表述格式里边加入链接来引导客户端。在《RESTful Web Services》一书中,作者把这种具有链接的特性成为连通性。下面我们看一个github的栗子。

        ```javascript
        # Request
        GET https://api.github.com/orgs/github HTTP/1.1
        Accept: application/json
    
        #Response
        HTTP/1.1 200 OK
        Link:<https://api.github.com/orgs/github/repos?page=2>;rel="next",
             <https://api.github.com/orgs/github/repos?page=3>;rel="last",
        Content-Type:application/json;charset=utf-8
    
        [
            {
                "id":"1296296",
                "url":"https://api.github.com/orgs/github",
                "name":"github"
                ...
            }
        ]

    我们注意到这个栗子里面多了一个Link参数的返回,里面带有了下个接口的请求地址等信息,这是符合RESTful的规范的,这种返回结构能够更好的帮助我们去梳理业务流程。

    2.5 什么是状态的转移?

    REST原则中的无状态通信原则:客户端负责维护应用状态,而服务端维护资源状态,服务端不应该保存客户端状态

    客户端与服务端的交互必须是无状态的,并在每一次请求中包含处理该请求所需的一切信息。

    服务端不需要在请求间保留应用状态,只有在接受到实际请求的时候,服务端才会关注应用状态。

    这种无状态通信原则,使得服务端和中介能够理解独立的请求和响应。

    在多次请求中,同一客户端也不再需要依赖于同一服务器,方便实现高可扩展和高可用性的服务端。

    但有时候我们会做出违反无状态通信原则的设计,例如利用Cookie跟踪某个服务端会话状态,常见的像J2EE里边的JSESSIONID。

    这意味着,浏览器随各次请求发出去的Cookie是被用于构建会话状态的。

    当然,如果Cookie保存的是一些服务器不依赖于会话状态即可验证的信息(比如认证令牌),这样的Cookie也是符合REST原则的。

    “会话”状态不是作为资源状态保存在服务端的,而是被客户端作为应用状态进行跟踪的。客户端应用状态在服务端提供的超媒体的指引下发生变迁。服务端通过超媒体告诉客户端当前状态有哪些后续状态可以进入。

    这些类似”下一页”之类的链接起的就是这种推进状态的作用——指引你如何从当前状态进入下一个可能的状态。

3.如何设计 RESTful API

阅读完了上述概念之后我们应该遵循如下的一些规范来进行RESTful API的设计:

  • 协议
  • 域名
  • 版本
  • 路径
  • HTTP动词
  • 过滤信息(Filtering)
  • 状态码(Status Codes)
  • 错误处理(Error handling)
  • 返回结果
  • Hypermedia API
  • 其他

    3.1协议

    协议指的是我们请求的接口地址是采用http协议还是https协议。

    3.2域名

    域名指的是我们请求的接口地址所在的服务器域名,例如:api.example.com。

    3.3版本

    版本在我看来其实不是完全必要的,在于一些中小项目,或许更新不是那么频繁或者不需要去字面跟新,可以省去版本号。但对于一些大型项目的话,版本号还是比较有用的,当出现了bug的时候,可能我们已经更新了一堆的版本,这样有版本号的话我们很方便的可以去追溯这个问题。

    通常的建议是把版本号放入到url中,例如https://api.example.com/v1/

    3.4路径

    路径又称”终点”(endpoint),表示API的具体网址。在RESTful架构中,每个网址代表一种资源(resource),所以网址中不能有动词,只能有名词,而且所用的名词往往与数据库的表格名对应。一般来说,数据库中的表都是同种记录的”集合”(collection),所以API中的名词也应该使用复数。

    比如说:

    3.5HTTP动词

    HTTP动词表示的是我们常用的请求方法:

    • GET(SELECT):从服务器取出资源(一项或多项)。
    • POST(CREATE):在服务器新建一个资源。
    • PUT(UPDATE):在服务器更新资源(客户端提供改变后的完整资源)。
    • PATCH(UPDATE):在服务器更新资源(客户端提供改变的属性)。
    • DELETE(DELETE):从服务器删除资源。

    例如我们上面的获取销售列表等就是GET请求。

    3.6过滤信息(Filtering)

    过滤信息指的其实就是条件查询,筛选符合我们条件的数据。这种通常都是前端提供额外的参数,然后后端根据参数进行筛选查询。

  • ?limit=10:指定返回记录的数量。

  • ?offset=10:指定返回记录的开始位置。
  • ?page=2&per_page=100:指定第几页,以及每页的记录数。
  • ?sortby=name&order=asc:指定返回结果按照哪个属性排序,以及排序顺序。
  • ?animal_type_id=1:指定筛选条件

    3.7状态码

    状态码指的是返回的请求状态code,也就是我们常见的200,500等。

    3.8错误处理(Error handling)

    良好的接口都应该能够友好的处理错误,譬如说当发生50x错误的时候,我们在返回体中编写:

    {
        message:'服务器端报错,这里错误的相对应描述'
    }
    3.9返回结果

    返回结果最好是处理后转化为JSON格式,对应的就是我们获取得到的结果,通常存放在data或者object等对象里面。

    3.10Hypermedia API

    这个含义其实就是上述github的栗子,我们推崇在返回的数据里面携带link属性等信息,方便我们梳理接下来的业务流程。

    3.11其他

    其他其实包含了一些认证等信息,比如说API的身份认证应该使用OAuth 2.0框架。单个接口只完成单个任务啊等等。

本篇文章是阅读了相关资料后的一个学习笔记,希望对大家都有所帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值