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】:

对于这两个模型,即。 countriesstates,我认为遵循 Uri 模式是最合适的。

    所有国家:api/country 具体国家:api/country/England 所有州:api/country/England/State 具体状态:api/country/England/State/Berkshire

在上面的例子中里面的值代表变量。

【讨论】:

@user2007820 嗨,这就是我的想法。现在请回复它,如果您有任何疑问。 嗨,好的,完美...但是,我需要同时按 ID 和名称进行搜索。我如何将其与请求区分开来? @user2007820 好的,您可以这样做,只需将 Id 后缀添加到 api,例如 api/countryId/12api/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 的概念

RESTful URL 设计:公共与私有 API、分层 API 设计模式、URI 与 URL 设计?

架构师之路 — API 经济 — RESTful API 设计规范原则

架构师之路 — API 经济 — RESTful API 设计规范原则