写点什么

RESTful API 为何成为顶流 API 架构风格?

  • 2023-02-10
    黑龙江
  • 本文字数:3493 字

    阅读完需:约 11 分钟

RESTful API 为何成为顶流 API 架构风格?

作者孙毅,API7.ai 技术工程师,Apache APISIX Committer


万物互联的世界充满着各式各样的 API ,如何统筹规范 API 至关重要。RESTful API 是目前世界上最流行的 API 架构风格之一,它可以帮助你实现客户端与服务端关注点分离,让前后端各自迭代,提升管理效率;其无状态的特性可以让应用更容易扩展,更容易的实现缓存策略从而提升系统性能和用户体验。本文将介绍什么是 RESTful API 以及我们如何使用它。


首先,抛开 API 这个概念,我们来聊聊在生活中如何传递信息。


当你在商店将钱拿给老板告诉他你需要买电池,老板在收到钱后在货架上找到电池并递给你。一个买电池的交易顺利完成。


计算机软件则通过 API 来完成信息的传递,先来看维基百科定义:


An application programming interface (API) is a way for two or more computer programs to communicate with each other. It is a type of software interface, offering a service to other pieces of software.


软件 A 通过 API 向软件 B 发起请求,软件 B 在查询自己资源后将请求的响应内容通过 API 返回 A。


软件 A 通过 API 向软件 B 发起请求就好比你跟老板说你需要电池,软件 B 在将数据返回给软件 A 就好比老板找到电池后将电池给你。


这一过程软件 B 不需要知道软件 A 为什么要数据,就好比商店老板不会问你买电池的目的。软件 A 也不需要知道 B 软件的数据是怎么找到的,就好比你买电池的时候你也不会问老板电池从哪里进货一样。每个软件之间通过 API 传递信息,各司其事,使得程序世界变得有序可靠。

什么是 RESTful API

Roy Fielding 在他 2000 年的博士论文《建筑风格和基于网络的软件架构设计》中定义了 REST(Representational state transfer),REST 架构风格定义了六个指导性约束。一个符合部分全部约束的系统被松散地称为 RESTful。



(图片来源:Seobility)

REST 的约束条件(长龙在排版时可以考虑一键截图 or 分点>横向叙述)

RESTful API 最佳实践

强调组件间的 统一接口 是 REST 架构风格与其他基于网络的风格区分开来的核心特征,基于此特征,本文梳理了 RSETful 最佳实践,以帮助你更好的设计 API。

路径名称避免动词

使用 HTTP 方法来表达资源操作行为,而不是将行为动词定义到路径中。


// Goodcurl -X GET http://httpbin.org/orders
// Badcurl -X GET "http://httpbin.org/getOrders"
复制代码


  • GET 获取指定 URI 的资源信息


// 代表获取当前系统的所有订单信息curl -X GET http://httpbin.org/orders
// 代表获取订单编号为 1 的订单详情信息curl -X GET http://httpbin.org/orders/1
复制代码


  • POST 通过指定的 URI 创建资源


 // 代表创建一个名称为 order 的资源curl -X POST http://httpbin.org/orders \  -d '{"name": "awesome", region: "A"}' \
复制代码


  • PUT 创建或全量替换指定 URI 上的资源


 // 代表将 id 为 1 的 order 进行数据替换curl -X PUT http://httpbin.org/orders/1 \  -d '{"name": "new awesome", region: "B"}' \
复制代码


  • PATCH 执行一个资源的部分更新


 // 代表将 id 为 1 的 order 中的 region 字段进行更改,其他数据保持不变curl -X PATCH http://httpbin.org/orders/1 \  -d '{region: "B"}' \
复制代码


  • DELETE 通过指定的 URI 移除资源


 // 代表将 id 为 1 的 order 删除curl -X DELETE http://httpbin.org/orders/1
复制代码

URI 使用复数形式

若使用单数的形式来表示获取某一类资源,例如:


curl -X GET "http://httpbin.org/order"
复制代码


使用单数形式,会使用户产生该系统中只有一个 order 的困惑,用复数形式在逻辑上则顺畅很多。


curl -X GET "http://httpbin.org/orders"
复制代码

善用 HTTP 状态码

HTTP 标准定义个状态码,大致可以分为以下几类:



使用标准状态码,开发人员可以立即识别问题,可以减少发现不同类型错误的时间。

版本管理

随着业务需求的变更,已经上线的 API 大概率是要对应调整的。如果我们的 API 有第三方在使用,让每一个客户端根据我们 API 的变更而变更显然是不可能的,这个时候就要引入 API 版本管理概念了,既可以保证历史 API 正常使用,又可以迭代新的 API 以满足新的业务需求。


常见的版本控制手段有:


  • 通过请求中路径来做版本控制


// 请求 v1 版本的APIcurl  http://httpbin.org/v1/orders
// 请求 v2 版本的APIcurl http://httpbin.org/v2/orders
复制代码


  • 通过 Query 参数来做版本控制


// 请求 v1 版本的APIcurl  http://httpbin.org/orders?version=v1
// 请求 v2 版本的APIcurl http://httpbin.org/v2/orders?version=v2
复制代码


  • 通过 Header 来做版本控制


// 请求 v1 版本的APIcurl  http://httpbin.org/orders -H "custom-version: v1"
// 请求 v2 版本的APIcurl http://httpbin.org/orders -H "custom-version: v2"
复制代码

APISIX 如何助力 RESTful API

作为一个动态、实时、高性能的 API 网关,Apache APISIX 可以在任何 RESTful API 服务上运行,并使用插件来添加新的服务和扩展其功能,这符合 RESTful 定义中的 Layered system。此外,对于一些没有遵循 RESTful API 定义的历史服务, APISIX 也可以帮你在不改动原有业务代码的情况下完成接口的转换,使你的接口完成 Uniform interface 这一 REST 限制条件,使你的 API 可以更好的遵守 RESTful API 规范。

分层系统:支持业务逻辑和安全逻辑的分割

你可以只用关注业务逻辑的实现,接口的安全逻辑可以交给 APISIX Authentication 类插件处理,例如 key-auth。APISIX 支持大量的 Authentication 插件,我们以 openid-connet为例如下图所示:



我们可以看到,使用 APISIX(API Gateway)在业务服务器前面加一层认证逻辑,就可以起到保护上游服务的作用,让你的业务逻辑和安全逻辑高效解耦。

Layered system:多负载均衡协议支持

APISIX 作为 API 网关,可以设立在客户端和服务端之间,完成不同的负载需求。你甚至可以自定义负载均衡的逻辑。


支持的负载均衡算法有:


  • roundrobin: Round robin balancing with weights.

  • chash: Consistent hash.

  • ewma: Pick the node with minimum latency. See EWMA Chart for more details.

  • least_conn: Picks the node with the lowest value of (active_conn + 1) / weight. Here, an active connection is a connection being used by the request and is similar to the concept in Nginx.

  • user-defined load balancer loaded via require("apisix.balancer.your_balancer")

统一接口:使历史 API 更加 RESTful

对于已经存在很久的历史 API,如果没有很好的遵循 RESTful API 准则。你可以在不改造原有 API 逻辑的情况下重新通过 APISIX 来封装新的 API 以满足不同的业务场景。

使用 proxy-rewrite 改写客户端请求

在本文中上方提过我们的路径中不要有动词。


例如:历史版本 API 有 /getOrder 接口,我们可以通过 proxy-rewrite 插件来将 API 请求代理到历史 API 上:


curl http://127.0.0.1:9080/apisix/admin/routes/1  -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '{    "methods": ["GET"],    "uri": "/orders",    "plugins": {        "proxy-rewrite": {            "uri": "/getOrder",            "scheme": "http",        }    },    "upstream": {        "type": "roundrobin",        "nodes": {            "127.0.0.1:80": 1        }    }}'
复制代码


你也可以同样使用该插件进行 API 版本管理上的操作。

使用 response-rewrite 插件改写服务端响应

当我们的历史 API 存在响应状态码不规范时,我们可以通过 response-rewrite 代理 response 响应从而达到修改响应状态码的目的。


curl http://127.0.0.1:9080/apisix/admin/routes/1  -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '{    "methods": ["GET"],    "uri": "/orders",    "plugins": {        "response-rewrite": {            "status_code": 201,            "body": "{\"code\":\"ok\",\"message\":\"new json body\"}",            "vars":[                [ "status","==",200 ]            ]        }    },    "upstream": {        "type": "roundrobin",        "nodes": {            "127.0.0.1:80": 1        }    }}'
复制代码


例如,这个例子表示将请求 /orders 路径的 API 中响应为 200 的状态的请求修改为 201。APISIX 支持非常丰富的插件,期待你去挖掘更多的玩法。

总结

本文详细说明了什么是 API,什么是 RESTful API 以及其最佳实践。另外还介绍了如何通过 APISIX 来实现业务逻辑和安全逻辑分离,如何使用 APISIX 在不改动原有业务代码的情况下将历史 API 服务更加 RESTful。希望本文对你了解 RESTful API 有所帮助,也欢迎你来 GitHub 一起玩耍。

发布于: 刚刚阅读数: 4
用户头像

https://apisix.apache.org/ 2021-06-02 加入

Apache APISIX 是一个动态、实时、高性能的云原生 API 网关,提供了负载均衡、动态上游、灰度发布、服务熔断、身份认证、可观测性等丰富的流量管理功能。

评论

发布
暂无评论
RESTful API 为何成为顶流 API 架构风格?_API_Apache APISIX 中文社区_InfoQ写作社区