首页 > 解决方案 > REST API url 设计

问题描述

我有一个 REST API,它有一个带有两列表的数据库,product_id并且server_id它为请求数据的特定服务器提供 product_ids(基于server_idfrom 表)。假设我有三台服务器,server_ids 为 1,2 和 3。

我的设计是这样的:/products/server_id/1通过 GET 请求,我得到了 server_id = 1 的 product_ids json 列表,同样/products/server_id/2会输出 product_ids 的列表server_id = 2

我是否应该删除这些路由并要求发送 POST 请求,其中包含/products仅在路由中接收特定 server_id 的 product_ids 的说明?

例如,发送有效载荷{"server_id":1}会产生一个 product_ids 列表的响应server_id = 1

标签: pythonapirestflaskpython-requests

解决方案


我是否应该删除这些路由并要求发送带有指令的 POST 请求,以仅在 /products 路由中接收特定 server_id 的 product_ids?

通常不会,不会。

GET向通用组件传达请求消息的语义实际上是只读的(参见“安全”)。仅这种可供性就使许多事情成为可能;例如,蜘蛛可以抓取和索引您的 API,就像它们对网站一样。用户代理可以“预取”资源,等等。

当您决定使用 POST 时,所有这些都会消失。

此外,URI 本身有许多有用的用途——缓存使用 URI 作为匹配请求的主键。因此,我们可以通过重用已使用特定标识符存储的表示来减少源服务器的负载。我们还可以执行魔术,例如将该 URI 粘贴到电子邮件消息中,而无需任何特定 HTTP 请求的上下文,并且消息的接收者将能够获取该标识符并获取我们想要的资源。

同样,当识别信息在请求有效负载中而不是在它所属的标识符元数据中时,我们会丢失所有这些信息。

也就是说,我们有时确实使用有效负载来识别信息,作为一种变通方法:例如,如果我们需要太多的识别信息以至于我们开始看到414 URI Too Long响应,那么我们可能需要更改我们的交互协议以使用带有有效载荷中的识别信息的 POST 请求(如上所述,失去了使用 GET 的优势)。

这方面的一个在线示例可能类似于 HTML 验证器,它接受候选文档并返回所发现问题的表示。这实际上是一个只读操作,但在一般情况下,HTML 文档太长,无法轻松放入 HTTP 请求的目标 uri。

所以我们踢。

超媒体 api中,就像在万维网上使用的那样,我们可以摆脱它,因为要使用的 HTTP 方法是由服务器提供的,作为表单本身元数据的一部分。您作为客户端不需要知道服务器的首选语义,您只需要知道如何处理表单数据。

例如,当我在浏览器中输入这个答案时,我不需要知道目标 URI 是什么,或者将使用什么 HTTP 方法,因为浏览器已经知道要做什么(基于 HTML 和任何内容)脚本正在“按需”运行)。


推荐阅读