API 风格 (一):RESTful API

简介

REST(REpresentational State Transfer 表现层状态转移),是一种软件架构风格,是一种架构约束条件和原则。它有一系列的规范。满足这些规范的 API 均可称为 RESTful API。

区别:REST 是一种规范,RESTful API 则是满足这种规范的 API 接口。

REST 规范把所有内容都视为资源,也就是说网络上一切皆资源

REST 架构对资源的操作有 获取(GET)、创建(POST)、修改(PUT)、删除(DELETE)。

HTTP方法行为URI说明
GET获取资源/users/admin获取 admin 用户的详细信息
POST创建资源/users创建一个新用户
PUT更新资源/users/admin更新 admin 用户
DELETE删除资源/users/admin删除 admin 用户

核心特点

  • 资源(resource)为中心。所有的东西都抽象成资源,所有的行为都是在资源上的 CRUD 操作。
    • 每个资源都有一个唯一的 URI 标识。例如,有一个用户名为 admin 的用户,可以使用 /users/admin 这个 URI 来进行标识。
  • 客户端通过 四种 HTTP 方法,对服务器端资源进行操作,实现 “表现层状态转化”。
  • 资源是有状态的。使用 JSON/XML 等在 HTTP Body 里表征资源的状态。
  • 无状态,指每个 RESTful API 请求都包含了所有 足够完成本次操作 的信息,服务器端无须保持 session。这对服务器的弹性扩容很重要。

RESTful API 设计原则

URI 设计

资源都是使用 URI 进行唯一标识的,通过规范化可以是 API 接口 更加易读、易用。

Google API Design Guide (谷歌API设计指南)中文版

参考链接

  1. URI 路径用小写,不要用大写。
  2. URI 结尾 不应包含 / 。
  3. URI 中不能出现下划线 _ ,必须用中划线 - 代替。
  4. 资源名 使用名词,并且用名词复数表示。资源分为 Collection 和 Member 两种。
    1. ·Collection:一堆资源的集合。例如系统中用户的集合就是 Collection。Collection 的 URI 标识应该是:https://xxx/users
    2. Member:单个特定资源。例如系统中特定名字的用户,就是 Collection 里的一个Member。 Member 的 URI 标识应该是 :域名/资源名复数/资源名称 ,例如:https://xxx/users/admin 。
  5. 避免 URI 层级过深。超过两层的资源嵌套就会很乱,应将其他资源转化成 ? 参数。例如:
     /schools/qdu/classes/rooma/students/zhang  # 不推荐
     /students?school=qdu&class=rooma           # 推荐

在实际的 API 开发中,可能 有些操作 不能很好的映射为一个 REST 资源。可以参考一下几点:

  1. 将一个操作 变成 资源的一个属性。
    // 在系统中禁用某个用户
    URI: /users/zhangsan?active=false
  2. 将操作 当做是一个资源的 嵌套资源。
    // Github 加减星操作
    PUT    /gists/:id/star   # github star action
    DELETE /gists/:id/star   # github unstar action
  3. 有时也可以打破这类规范。
    // 比如登录操作,不属于任何一个资源,URI 可以设计为:
    /login

REST 资源操作映射为 HTTP 方法

基本上 RESTful API 都是使用 HTTP 协议原生的 GET、POST、PUT、DELETE 来标识对资源的 CRUD 操作的,参考上面的表格。

对资源的操作应该满足安全性、幂等性:

  • 安全性:不会改变资源状态,可以理解为只读的。
  • 幂等性:执行 1 次 与 执行 N 次,对资源状态改变的效果是等价的。
HTTP方法安全性幂等性
GET
POST
PUT
DELETE

对于批量删除的需求,需要在请求中携带多个需要删除的资源名,但是 HTTP 的 DELETE 方法不能携带多个资源名,可以使用下面三种方式解决,三种方式有各自的使用场景,整个项目中最好使用统一的方式:

  1. 发起多个 DELETE 请求。
  2. (推荐)操作路径中携带多个 id,id 之间使用分隔符分隔。例如:DELETE /users?id=1,2,3 。这样既使用了 DELETE 动词,并且不需要发送多次 DELETE 请求。
  3. 直接使用 POST 方式,在 body 中传入需要删除的资源列表。        

返回格式

一个系统的 RESTful API 会向外界开放多个资源的接口,每个接口的返回格式要把持一致。每个接口都会返回成功、失败,这两种消息的格式也要保持一致。不然,客户端代码要适配不同接口的返回格式。

参考链接:待补充

API 命名 

API 命名方式:

  • 驼峰命名法(serverAddress)
  • 蛇形命名法(server_address)
  • 脊柱命名法(server-address)

建议使用:脊柱命名法。因为其它两种需要切换输入法,会增加操作的复杂性,也容易出错。

API 域名

API 的域名设置的两种方式:

  • https://domain.com/api

这种方式适合 API 将来不会有扩展的情况。比如起初 domain.com 域名下只有一套 API 系统,未来也只有这一套 API 系统。

  • https://user.api.domain.com

如果 domain.com 域名下未来会新增另一个系统 API,最好每个系统的 API 拥有专有的 API 域名。比如:storage.api.domain.com、network.api.domain.com。

API 版本管理

随着时间推移、需求变更,当一个 API 满足不了现有的需求,就需要修改 API。对 API 进行修改,不能影响其他调用系统的正常使用,要做到向下兼容,也就是新老版本共存。

但是,实际场景中很可能会出现同一个 API 无法向下兼容的情况。最好的解决办法就是从一开始就引入 API 版本机制。当不能向下兼容是,就引入一个新的版本,老的版本保留原样。这样既可以保证服务的可用性、安全性,同时也能满足新需求。

在 RESTful API 开发中,通常将版本标识放在如下 3 个位置:

  • (推荐)URL 中, 比如:/v1/users 。
  • HTTP Header 中,比如:Accept: vnd.example-com.foo+json; version=1.0 。
  • Form 参数中,       比如:/users?version=v1 。

统一 分页 / 过滤 / 排序 / 搜索 功能

REST 资源的查询接口,通常情况下都需要实现分页、过滤、排序、搜索功能。这些功能是每个 REST 资源都能用到的,所以可以实现一个公共的 API 组件

  • 分页

在列出一个 Collection 下所有的 Member 时,应该提供 分页功能。例如:

/users?offset=0&limit=20 (offset:指定返回记录的开始位置;limit:指定返回记录的数量)

引入分页功能,可以减少 API 响应的延时;同时可以避免返回太多条目,导致服务器 / 客户端响应特别慢,甚至出现 crash 的情况。

  • 过滤

如果用户不需要一个资源的全部状态属性,可以在 URI 参数里指定返回那些属性。例如:

/users?fields=email,username,address 。

  • 排序

很多时候会根据 创建时间或者其他因素,列出一个 Collention 中前 100 个 Member,可以在 URI 参数中指明 排序参数。例如:

/users?sort=age,desc 。

  • 搜索

当一个资源的 Member 太多的时候,可以按 模糊匹配 的搜索方式,来快速找到所需要的 Member,或者查看是否有名字为 xxx 的资源。

练习

使用 net/http 包,实现一个 RESTful API 服务,访问 /hello 接口,返回 “Hello World” 字符串。

源码文件

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值