Skip to main content

REST API

遵循 REST 架构约束的 Web service API 就被称为 REST API(也叫 RESTful API)。本项目涉及的接口实现全部遵循 REST 风格。

REST 的设计思路是「万物皆资源」,对于习惯了面向对象的程序员来说是反直觉的,因为业务代码中还是一个个的动作函数,而接口的呈现完全是资源形式。REST 不是唯一的选择,采用 RPC 风格同样可以出色的完成功能实现。采用 REST 风格的前提是充分理解它,否则会带了更多的混乱。

什么是 REST ?#

深入了解 REST API 之前,先了解一下 REST。REST 是一种架构风格( architectural style),用于指导 Web 应用的设计与开发。它提供了一组架构约束(constraints),强调组件交互的可伸缩性、接口的通用性、组件的独立部署、以及用来减少交互延迟、增强安全、封装遗留系统的中间组件。

REST 概念来源于 Roy Fielding 博士发表于2000年的论文。Roy Fielding 博士是 HTTP 协议规范的主要作者、 Apache HTTP Server 项目的共同创始人。论文探讨的是计算机科学两个研究课题——软件(Software)和网络(Networking)——的前沿的交叉点。软件研究长期关注于软件设计分类和设计方法论的发展,但是却很少客观地评估不同设计选择对系统行为的影响。相比之下,网络研究关注系统之间通信行为细节以及改善特定通信技术的性能,却忽略了改变一个应用的交互风格能够比改变用于交互的通信协议对性能产生更多影响的事实。


REST API 的好处#

  • API 语义清晰,更容易被调用者理解
学生转班
RPC style : POST /student/transfer //以数据模型为中心的设计思路且遵循Information Expert设计模式下的产物
REST style :POST /classes/:class/students/:student/transfer

信息专家模式(Information Expert)是GRASP模式中解决类的职责分配问题的最基本的模式。

  • 充分利用命名空间,API命名不再混乱
POST /accounts/:account/orders/ //用户下单
POST /tenants/:tenant/orders/ //商户下单
POST /contests/tests/:test/contesttants //测试类比赛报名
POST /contests/games/:contest/contesttants //游戏类比赛报名
  • 对于开发者来说 为“哪些参数应该放到 URL 的路径中(以及哪些参数应该放到 URL 的查询参数中),哪些参数应该放到 Body 中”的问题提供了指导
我们考虑一个场景:将 A 班的学生 王某某 转到 B 班。
其中,“A 班的学生 王某某”是操作对象(即一个资源),转班是操作(具化为转班记录),“B 班”操作内容。
因此,API 可以设计为:
POST /classes/A/students/王某某/transfer
{"toClass":"B"}

设计原则#

  • 以 API Consumer 的视角去抽象资源,而不是数据模型、业务逻辑的视角
正例:
POST /classes/:class/students/:student/transfer
反例:
POST /students/:student/transfer 数据模型、业务逻辑的视角
  • 资源应该是从 API Consumer 视角讲得通的名词,而不是动词
  • 充分利用 HTTP 协议中的动词(GET、POST、PUT、PATCH、DELETE)
正例:
POST /classes/:class/students 入班
DELETE /classes/:class/students 退班
反例:
POST /classes/:class/students 入班
POST /classes/:class/deleted_students 退班
  • 对于不适用 CRUD 资源操作的Action,重构以使其看上去像是一个资源的字段,或将其视为符合 REST 规则的子资源
重构以使其看上去像是一个资源的字段
POST /accounts/:account/transactions //转账
视为符合 REST 规则的子资源
POST /classes/:class-id/students/:student/suspending //学生休学
DELETE /classes/:class-id/students/:student/suspending //学生复课
  • 版本号应包含在路径中
GET /v1/classes/:class/students
GET /v2/classes/:class/students
  • 有些情况是无法用 REST API 来呈现的,这时只要以 API Consumer 的视角理解不产生混乱即可
系统初始化配置
POST /setup/configure

命名规范#

  • 【强制】资源 URI 必须是名词,且全部为小写英文字母
  • 【强制】资源 URI 不能含有文件后缀
  • 【强制】资源 URI 不能含有 CRUD 函数名(通过 HTTP 方法表示)
  • 【强制】使用斜杠线 (/) 来表示 URI 的层级,URI 的末尾无斜杠线
  • 【强制】资源 URI 使用连字符 ( - ) 来提高 URI 的可读性,避免使用下划线 ( );URI 中的参数使用下划线 ( ),避免使用连字符 ( - )
GET /advance-classes/:class_id
  • 【强制】用 query 语法来过滤集合,避免使用层级分割符

REST API 实现参照#

Gighub REST API

PayPal REST API