RESTful URI 设计
Posted
技术标签:
【中文标题】RESTful URI 设计【英文标题】:RESTful URI design 【发布时间】:2013-03-09 11:20:42 【问题描述】:我正在寻找一种将搜索表示为 RESTful uri 的正确方法。
我有两个模型:国家和国家,国家有一个集合国家。
用 id 或 name 属性表示对国家/地区的搜索的正确方法是什么?
api/countries/1/id
api/countries/Italy/name
或
api/countries?id=1
api/countries?name=Italy
另外,如果我想查看状态列表?
api/countries/1/id/states
api/countries/Italy/name/states
谢谢
【问题讨论】:
【参考方案1】:对于这两个模型,即。 countries
和 states
,我认为遵循 Uri 模式是最合适的。
-
所有国家:
api/country
具体国家:api/country/England
所有州:api/country/England/State
具体状态:api/country/England/State/Berkshire
在上面的例子中里面的值代表变量。
【讨论】:
@user2007820 嗨,这就是我的想法。现在请回复它,如果您有任何疑问。 嗨,好的,完美...但是,我需要同时按 ID 和名称进行搜索。我如何将其与请求区分开来? @user2007820 好的,您可以这样做,只需将Id
后缀添加到 api,例如 api/countryId/12
,api/countryId/12/stateId
。或者,您也可以在不更改 url 的情况下这样做。为此,您需要在数据库中的 namefiled 以及 Id 字段中搜索参数值。希望你明白了。请回复:)
因此,在您看来,正确的方法是:/api/countryid/12/states
=> id 为 12 的所有国家/地区 /api/countryname/Italy/states
=> 名称为意大利的所有国家/地区 谢谢
是的,对于您的 Rest Api,这将是更不言自明的 uri。用户可以很容易地理解这个 url 将被返回的内容。所以就去吧,是的,请将其标记为答案:)【参考方案2】:
这取决于你的口味。两种变体都可以。
对于状态,可以创建新端点
api/states/name/Italy
【讨论】:
【参考方案3】:您在 REST URL 中使用名称的方法是错误的。该名称只是国家的一个属性,而不是子资源,这意味着您不应该在 URL 中看到它。但是,可以选择将其用作键,在这种情况下,可以使用名称的 值 代替 ID。
api/countries/Italy
我认为您想要实现的是过滤字段,即仅获取名称:
api/countries/Italy/states?fields=name
或者,如果您预定义了某些格式
api/countries/Italy/states?format=onlyName
【讨论】:
【参考方案4】:用 id 或 name 属性表示对国家/地区的搜索的正确方法是什么?
tl;dr:变体一是混淆的秘诀。如果必须选择,请使用 查询字符串 来搜索。
就 REST 宣言而言,URI 逻辑只是一个实现细节——唯一需要关注的是该位置的访问机制不能随着时间的推移而中断。内容可能会被清空或移动 - 但 URI 必须始终以服务端点结束,该端点为客户端提供他们理解并可以采取行动的预响应(即客户端的 3** 重定向或超媒体重新发现)。
但是,许多成功且设计良好的 API 都试图公开内在一致的逻辑,旨在变得直观可探索。因此,您的第一个示例 api/countries/1/id
实际上 BAD 关于开发人员的经验和市场成功,因为它使用起来令人困惑:
-
通过查看 URI,您没有任何线索表明您正在运行(可能会占用大量 CPU/内存)搜索而不是检索单个资源
许多公共 API 遵循资源层次结构和公开的 URI 之间的逻辑映射 - 因此常见的期望是
api/countries/1/id
检索 1
(作为一个毫无意义的查询)或 api/countries/1/name
给出 Italy
。李>
因此,Query 字符串是一个很好的选择——尤其是提供 Search 功能。从字里行间就能看出来;)
api/countries?name=Italy
api/countries?q=name(Ital*) // same result
api/countries?q=isoCode=(IT) // same result
--> api/countries/1/states // list all states of Italy
api/states?q=country/name(Italy) // - same -
api/states?q=country/id(1) // - same -
仅通过查看 URI 就可以预期请求的响应正文,这很好。更好的是:它有助于区分资源和视图。 “视图”在查询字符串中定义,可将其视为镜头或过滤器,通过它您可以查看相同资源(您的国家/地区集合)的摘录。
这种模式在这些方面同样出色,也很常见:
api/countries/search/Italy
api/countries/search/name=Italy
api/countries/search/isoCode=IT,name=*aly
选择此选项的原因可能与构建 API 时的实际实现细节有关 - 因为它将直接访问资源与搜索操作分开 - 满足请求所需的 CPU/内存以及响应计数和格式可能根本不同。
【讨论】:
以上是关于RESTful URI 设计的主要内容,如果未能解决你的问题,请参考以下文章
API 端点是不是可以根据用户凭据 RESTful 和良好的 URI 设计来区分要返回的资源?
RESTful API 设计 - 使用资源 URI 与 ID
RESTful URL 设计:公共与私有 API、分层 API 设计模式、URI 与 URL 设计?