RESTful API 设计

许多开发人员在使用和构建 REST 应用程序接口时,并不了解什么是 RESTful。那么,什么是 RESTful?此外,为什么 API 必须是 RESTful 的?

RESTful 应用程序接口有一些关键的架构限制,其中第一条就是无状态。

无状态特性

RESTful API 是无状态的;客户端的上下文在请求之间不会存储在服务器上。

假设你创建了一个具有登录功能的基本 PHP 应用程序。在验证了登录表单中的用户凭据后,您可以继续使用会话来存储登录用户的状态,因为他们将继续进行下一个状态以执行下一个任务。

当涉及到 REST API 时,这是不可接受的;REST 是一种无状态协议。REST 中的 ST 代表状态转移;请求的状态应该被传输,而不仅仅是存储在服务器上。通过传输会话而不是存储会话,可以避免出现粘性会话或会话相关性。

为了实现这一目标,HTTP 请求完全独立发生。服务器执行 GETPOSTPUTDELETE 请求所需的一切都在 HTTP 请求本身中。服务器从不依赖来自先前请求的信息。

这样做的好处是什么?首先,它的伸缩性更好;最明显的好处是,你根本不需要在服务器上存储会话。当您将 API Web 服务器置于负载均衡器之后时,它还附带了其他功能。

聚类分析很困难;将一个 web 服务器与状态进行集群,意味着你需要有粘性负载均衡,或者在会话方面需要有一个公共存储。

版本控制

如果您的应用程序接口版本升级,您将需要进行更改,但您不希望这些更改破坏您的客户端实现。这可以通过标头或 URL 本身来实现。例如,您可以用 /api/v1/resource.json 代替 /api/resource.json

您也可以使用 HTTP Accept 标头来执行此行为,甚至可以设置自己的标头。客户端发送请求时可以将 API-Version 标头设置为 2,这样服务器就会知道要使用 API 的版本 2 与客户端通信。

过滤

使用参数查询,我们可以通过参数对给定内容进行过滤。如果我们处理的是 /orders 端点上的订购系统,那么实现基本过滤就相当容易。

在这里,我们使用 state 参数过滤未结订单:

GET /orders?state=open

排序

我们还可以为按字段排序添加一个排序参数。排序字段反过来又包含一个用逗号分隔的列列表,列表中的第一列排序优先级最高。为了进行负排序,需要在列的前缀加上负号(-)。

  • GET /tickets?sort=-amount:按金额降序排列订单(从高到低)。

  • GET /tickets?sort=-amount,created_at:按金额降序排列订单(从高到低)。在这些金额(具有相同金额的订单)中,较旧的订单首先列出。

搜索

然后,我们可以使用一个简单的参数进行搜索,该参数可应用搜索查询,然后通过搜索服务(例如 ElasticSearch)进行路由。

假设我们想搜索订单中的退款短语,我们可以定义一个用于搜索查询的字段:

GET /orders?q=refund

限制字段

此外,使用 fields 参数我们可以查询特定字段:

GET /orders?fields=amount,created_at,customer_name,shipping_address

返回新字段

PUTPOSTPATCH 除更新字段外,还可以更改其他条件。这可能是新的时间戳或新生成的 ID。因此,我们应该在更新时返回新的资源表示。

在创建了资源的 POST 请求中,可以发送 HTTP 201 CREATED 消息,同时发送指向资源的 Location 头信息。