用 id 或 name 属性表示搜索国家/地区的正确方法是什么?
tl; dr:变体一是混淆的秘诀。如果必须选择,请使用查询字符串进行搜索。
就 REST 宣言而言,URI 逻辑只是一个实现细节——唯一需要关注的是该位置的访问机制不能随着时间的推移而中断。内容可能被清空或移动 - 但 URI 必须始终以服务端点结束,该端点为客户端提供他们理解并可以采取行动的预响应(即 3** 重定向或客户端的超媒体重新发现)。
然而,许多成功且设计良好的 API 都试图公开内在一致的逻辑,旨在变得直观可探索。因此,关于开发人员的经验和市场成功,您的第一个示例 api/countries/1/id
实际上是不好的,因为它使用起来令人困惑:
- 通过查看 URI,您没有任何线索表明您正在运行(可能是 CPU/内存昂贵的)搜索而不是检索单个资源
- 许多公共 API 遵循资源层次结构和公开的 URI 之间的逻辑映射 - 因此常见的期望是
api/countries/1/id
检索{1}
(作为无意义的查询)或api/countries/1/name
给出{Italy}
.
因此,查询字符串是一个很好的选择——尤其是提供搜索功能。从文字中可以看出含义;)
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/内存以及响应计数和格式可能从根本上是不同的。