ChatGPT解决这个技术问题 Extra ChatGPT

何时在 RESTful API 中使用路径参数与查询参数?

我想让我的 RESTful API 非常可预测。决定何时使用 URI 而不是使用查询参数对数据进行分段的最佳实践是什么?

对我来说,支持分页、排序和分组的系统参数在“?”之后是有意义的。但是像“状态”和“区域”这样的字段或其他划分您的收藏的属性呢?如果这些也是查询参数,那么知道何时使用路径参数的经验法则是什么?

这里回答了一个类似的问题... stackoverflow.com/questions/3198492/…

M
Mike

RESTful API 设计的最佳实践是路径参数用于标识特定资源或资源,而查询参数用于对这些资源进行排序/过滤。

这是一个例子。假设您正在为名为 Car 的实体实现 RESTful API 端点。您将像这样构建端点:

获取 /cars
获取 /cars/:id
发布 /cars
放置 /cars/:id
删除 /cars/:id

这样,您仅在指定要获取的资源时使用路径参数,但这不会以任何方式对资源进行排序/过滤。

现在假设您想在 GET 请求中添加按颜色过滤汽车的功能。因为颜色不是资源(它是资源的属性),所以您可以添加执行此操作的查询参数。您可以像这样将该查询参数添加到您的 GET /cars 请求中:

获取/cars?color=blue

将实施此端点,以便只返回蓝色汽车。

就语法而言,您的 URL 名称应全部小写。如果您的实体名称通常是英文中的两个单词,您将使用连字符来分隔单词,而不是驼峰式。

前任。 /two-words


谢谢你的回答迈克。这是一种清晰而简单的方法;值得我投赞成票。尽管如此,开发人员经常选择“汽车/蓝色”方法,我想知道他们这样做的理由是什么......也许他们决定为必填字段制作路径参数,或者他们这样做是为了表明数据库由该分片分区。
我不确定他们的推理是什么。老实说,我不同意。我认为遵循惯例并保持简单是最有意义的。通过这样做,您可以让 API 的使用者更好地了解他们需要做什么才能访问它的功能。
/cars?id=1&color=blue 而不是 cars/1/?color=blue。您基本上是在每种情况下过滤汽车资源
错误,因为 ID 为 1 的汽车只存在一辆,但蓝色的汽车可能很多。身份和过滤器有区别
有趣的琐事,this-is-called-kebab-case
c
cosbor11

思考这个问题的基本方法如下:

URI 是唯一标识资源类型的特定实例的资源标识符。像生活中的其他事物一样,每个对象(它是某种类型的实例)都具有一组时不变或临时的属性。

在上面的示例中,汽车是一个非常有形的物体,具有品牌、型号和 VIN 等属性——它们永远不会改变,而颜色、悬架等可能会随着时间而改变。因此,如果我们使用可能随时间(时间)变化的属性对 URI 进行编码,我们最终可能会得到同一个对象的多个 URI:

GET /cars/honda/civic/coupe/{vin}/{color=red}

多年后,如果这辆车的颜色变成黑色:

GET /cars/honda/civic/coupe/{vin}/{color=black}

请注意,汽车实例本身(对象)没有改变——只是颜色改变了。让多个 URI 指向同一个对象实例将迫使您创建多个 URI 处理程序——这不是一种有效的设计,当然也不直观。

因此,URI 应该只包含永远不会改变的部分,并且将在其整个生命周期内继续唯一标识该资源。所有可能改变的东西都应该保留给查询参数,例如:

GET /cars/honda/civic/coupe/{vin}?color={black}

底线 - 考虑多态性。


有趣的范式..这是一种常用的设计模式吗?您能否提供一些在其文档中使用它的 API 或概述此策略的一些参考资料?
我喜欢您在编写“URI 是唯一标识资源类型的特定实例的资源标识符”时强调“类型”的方式。我认为这是一个重要的区别。
这是最有意义的。我认为路径变量有助于使参数更清晰、更易于理解。
这是 REST-API 设计中的一个非常好的观点和规则:URI should only consist of parts that will never change and will continue to uniquely identify that resource throughout its lifetime
u
user1717828

在 REST API 中,您不应该过度关注可预测的 URI。 URI 可预测性的建议暗示了对 RESTful 架构的误解。它假定客户端应该自己构建 URI,而他们实际上不应该这样做。

但是,我假设您不是在创建一个真正的 REST API,而是一个“受 REST 启发”的 API(例如 Google Drive 之一)。在这些情况下,经验法则是“路径参数 = 资源标识”和“查询参数 = 资源排序”。那么,问题就变成了,您能否在没有状态/区域的情况下唯一标识您的资源?如果是,那么它可能是一个查询参数。如果不是,那么它是一个路径参数。


我不同意,一个好的 API 应该是可预测的; RESTful 或其他。
我认同。 URI 的形成方式应该有韵律和理由,而不是任意命名端点。当一个人可以在不经常参考文档的情况下直观地编写 API 客户端时,我认为你已经编写了一个很好的 API。
“当一个人可以直观地编写 API 客户端而无需经常参考文档时”。这就是我认为我们对 REST 的理解不同的地方...... API 客户端永远不需要“构建”一个 URL。他们应该从上一个 API 调用的响应中选择它。如果您将网站作为类比...您访问 facebook.com,然后选择指向活动页面的链接。您不在乎 facebook 事件 URL 是否“可预测”,因为您没有输入它。您可以通过超媒体链接到达那里。 REST api 也是如此。因此,使 URI 对您(服务器)有意义,但对客户端没有意义
添加注释。这并不意味着 URI 不应该遵循易于理解的模式,它只是意味着它不是 RESTful API 的约束。这个领域最大的问题是人们假设客户端应该自己构建 URL。他们不应该,因为这会在客户端和服务器之间创建不应该存在的耦合。 (例如,服务器不能在不破坏所有客户端应用程序的情况下更改 URL)。在 REST API 中,服务器可以随意更改它们。
+1 使用以下词语:“'路径参数 = 资源标识'和'查询参数 = 资源排序'”。这真的为我清除了它。
w
webmaster_sean

分割更具层次性和“漂亮”,但可能会受到限制。

例如,如果您有一个包含三个部分的 url,每个部分传递不同的参数以通过品牌、型号和颜色搜索汽车:

www.example.com/search/honda/civic/blue

这是一个非常漂亮的 url,更容易被最终用户记住,但现在你有点坚持这种结构。假设您想让用户在搜索中搜索所有蓝色汽车或所有本田思域?查询参数解决了这个问题,因为它提供了一个键值对。所以你可以通过:

www.example.com/search?color=blue
www.example.com/search?make=civic

现在您可以通过它的键来引用该值 - 查询代码中的“颜色”或“制作”。

您可以通过可能使用更多段来创建一种键值结构来解决这个问题,例如:

www.example.com/search/make/honda/model/civic/color/blue

希望这是有道理的..


我认为这就是资源概念的来源。品牌和颜色不是资源。 /cars 是一种资源。也许如果您有不同的车库出售汽车,那么 /cars/[garage]/ 是一种资源。然后,您可以搜索所有汽车的品牌和颜色,或者在车库中搜索品牌和颜色。
C
Community

一旦我设计了一个主要资源是 people 的 API。通常用户会请求过滤的 people,因此,为了防止用户每次都调用 /people?settlement=urban 之类的东西,我实现了 /people/urban,它后来使我能够轻松添加 /people/rural。如果以后有任何用处,这也允许访问完整的 /people 列表。简而言之,我的推理是为公共子集添加路径

here

常见查询的别名 为了让普通消费者的 API 体验更愉快,请考虑将条件集打包到易于访问的 RESTful 路径中。例如,上面最近关闭的门票查询可以打包为 GET /tickets/recently_closed


J
Janac Meena

考虑一下“路径”这个词——一种到达某个位置的方式。路径参数应该描述如何到达您感兴趣的位置/资源。这包括目录、ID、文件等。

/vehicles/cars/vehicle-id-1

这里,vehicle-id-1 是一个路径参数。

考虑“查询”这个词 - 我认为它是询问有关路径的问题,即我的路径是蓝色的,我的路径是否有 100 个结果。

/vehicles/cars/vehicle-id-1?color=blue&limit=100

这里的 color=bluelimit=100 是查询参数,它们有助于描述我们在获得资源后应该做什么:过滤掉蓝色的,并将它们限制为 100 个结果。


m
morsor

一般来说,当资源中存在明显的“层次结构”时,我倾向于使用路径参数,例如:

/region/state/42

如果该单一资源具有状态,则可以:

/region/state/42/status

但是,如果“区域”实际上不是所公开资源的一部分,则它可能属于查询参数之一-类似于分页(如您所述)。


G
Grant Foster

示例网址: /rest/{keyword}

此 URL 是路径参数的示例。我们可以使用 @PathParam 获取此 URL 数据。

示例网址: /rest?keyword=java&limit=10

此 URL 是查询参数的示例。我们可以使用 @Queryparam 获取此 URL 数据。


问题是“何时”使用它们,而不是“如何”使用它们。此外,@PathParam 和@QueryParam 是特定于语言的,因此对特定人群没有帮助。

关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅