谈谈对 RESTful 的认识

还记得几个月前,我去面试的时候,面试官(也就是现在的同事)问了我一个问题:『你觉得什么是 RESTful?』,我当时的问答是:『RESTful API 都是围绕资源进行设计的,每个 URL 代表一种资源』,面试官补充说了一句:『 URL 里只能有名词,不能有动词。』

现在再去想这个问题,我很庆幸自己对 RESTful 的认识并不只停留在 API 的设计方面,下面详细的说说,我对 Restful 的理解

首先我想先解释一下 REST, RESTful, ROA 这些常被提及的名词到底是什么含义

  • ROA: 面向资源的架构 (Resource-Oriented Architecture)
    面向资源的架构(ROA)意味着,作用域信息都在 URI 里

  • REST: 表现层状态转化 (Representational State Transfer)
    REST 并不是一种架构,而是一组设计原则

  • RESTful: REST 式
    如果一个架构符合 REST 原则,就称它为 RESTful 架构

好了,搞懂这几个名词之后,我来说说对下面几个问题的认识

Q: RESTful 服务的特点

  • 面向资源的架构(ROA)

  • REST 式服务的方法信息都在 HTTP 方法里 (统一接口原则)

    • 公用一套标准词汇,即 HTTP 方法
    • 服务里的每个对象都具有统一的基本接口
    • 资源响应的是标准的 HTTP 方法
       
  • REST 式服务的作用域信息都在 URI 里 (可寻址性原则)
    • 资源是通过 URI 暴露的
    • 可寻址的 web 服务会为它提供的每一则信息(资源)都发布一个 URI
      (PS: 可寻址的含义:应用将其数据集里有价值的部分作为资源发布出来)
       
  • 无状态性
    • 要求服务器可能的状态也是资源,也有自己的 URI
    • 当客户端发出一个 HTTP 请求时,请求里包含服务器实现该请求所需的全部信息,不依赖任何之前请求提供的信息
       
  • 连通性
    • 资源应当通过超媒体的表示将彼此连接起来

Q: REST 式和 RPC 式架构的区别

  • RPC 式架构通过一个复杂的、编程语言式(函数式)的接口,来暴露其内部的算法;

  • 各个 RPC 式服务的方法采用自己的词汇,就像定义函数名那样;许多 RPC 式 Web 服务都是由它们内部的实现方法自动生成的,它们暴露的服务接口跟它们在内部调用的编程语言接口是一样的;

  • RPC 式服务忽略了 HTTP 方法,在 URI、HTTP 报头或实体主体里找到方法信息和作用域信息;

Q: 如何设计 RESTful API

通常我们在谈论 RESTful 的时候,更多的是在谈论如何设计 RESTful API。那么满足 RESTful web services 特点的 API 应该是什么样的?

因为在 RESTful 的架构中,web 服务的每个 URI 都对应一种资源,所以这个问题换一种问法就是:如何命名资源

  • 因为资源表示一种实体,所以应该是名词,URI 不应该有动词,动词应该放在服务的方法信息里

  • 用路劲变量来表达层次结构,例如:
    /parent/child

  • 用查询变量(query)来表达算法的输入,例如:
    /search?q={query}


PS: 从1月1日开始实习,到现在也实习了三个月了(但中间还放了一个月的寒假),get 到了好多技能,我打算逐一慢慢写

细细数起来,有好多想写的东西:比如基于 flask 的微服务是什么样的,redis 的使用,celery 处理异步任务,数据库索引/事务/锁,对 restful api 的认识,进程间的通信….等等等等

今天就先从 restful API 开始写,争取每周产出一篇 (Flag :D