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

     2023-03-31     219

关键词:

【中文标题】RESTful URL 设计:公共与私有 API、分层 API 设计模式、URI 与 URL 设计?【英文标题】:RESTful URL design: public vs private API, hierhachy API design pattern, URI vs URL design? 【发布时间】:2013-12-19 23:00:23 【问题描述】:

我经常遇到这样的问题,与Hierarchical RESTful URL design非常相似

假设该服务仅提供用户上传文档。

POST, GET /accounts
PUT, DELETE /accounts/name  or /accounts/id

现在一个文档被附加到一个特定的用户,不管它是不是公开的,这里都不关心。

两种方式是POST /documents vs POST /users/documents

为什么?因为稍后创建文档资源时,该文档处于用户的控制之下。所以我希望有

GET, PUT, DELETE /users/name/documents 用于获取、更改和删除用户拥有的一堆文档。

我可以有GET, PUT, DELETE /users/name/documents/name/id

但是/documents/users/.... or /documents/id 也可以达到同样的效果。这类似于组织 unix 文件的方式(尽管/users/... 也是组织文件的另一种方式......)你看,还有一种哲学[phy of uri vs url design。

另一个考虑因素是 API 是否对用户可见。如果这只是一个后端 API,只有开发人员可以访问(backend <- frontend server <- frontend ajax),那么网站用户可能会更喜欢/users/name/documents/id/name,而如果 API 是公开的(如 twitter api),一些程序员会不喜欢这个长 url。

人们如何看待这些问题?

【问题讨论】:

【参考方案1】:

从务实的角度来看,显然以上所有内容都是正确的。

但从哲学上讲,我认为它归结为 REST 中的“S”......这实际上是一个问题,即您管理状态的资源实际上是什么。如果您的应用程序旨在处理文档,那么这需要是 URL 中明显的资源。如果您的应用更多地是关于用户执行某些工作流,那么您可能希望让用户在 URL 中显而易见。

在应用程序内部,为了方便起见,事情很快就会建立起来,这样您就可以拥有混合和匹配资源的 URL,以使所有权明显(如您的示例中所示)。这样想吧。用户使用您的应用来处理他们的东西,其中一些是文档。他们知道他们已登录,然后他们可以访问他们的文档,他们的一些信息在会话中与他们一起传播,并且从这个角度来看

user/name/documents

有道理。他们有上下文。

如果您将该 API 公开...也就是说,如果与您的应用程序中的用户没有相同观点的人正在使用您的 API...那么该公开面孔需要在语义上清晰 - 是用户裸露?文件?消费者是否关心谁拥有该文件?该 API 就像一个目录;应该会有帮助的。

因此,如果您的 api 与其他应用程序的合同是您的应用程序正在公开文档,那么我会说您最好在您的 URL 中明确这一点。到用户的路由的概念在这里没有意义,因为上下文与合同无关。

你提出了一个有趣的例子,非常清楚地表明了这一点。采取

document/iddocument/name

文件的命名可以遵循约定或特定于应用程序。很好的例子是图像共享应用程序或特定行业的应用程序,如会计。但是公共 API 不能假定命名约定是显而易见的(除非您允许 API 的使用者访问此类信息)。因为它是一个面向公众的 API,所以最好还是使用

document/id

因为 id 通常被认为是不可变的,即使跨 API 也是如此,并且语义非常清晰。

最终,这项技术可以做我们想做的任何事情。但是路由和 URL 之类的东西对于理解 API 本身的语义很重要。如果您正在管理某事,那么在使用 API 时这应该是显而易见的,并且不应该被您的本地或技术特定的约定所困扰。

【讨论】:

【参考方案2】:

好的,您无疑会遇到、研究或偶然发现一些约定。然而,虽然我在这里可能不是 100% 正确,但现在暂时搁置惯例。

在编写 RESTful 服务时,首先要考虑流程的层次结构以及谁拥有什么。换一种说法。如果我想删除属于一组人的文档,我不会写像 /user/doc/id 这样的 url。 /user/doc/id 之类的东西通常在逻辑上意味着您首先处理与用户相关的内容,然后是文档,然后是该用户的特定文档。

所以我想说的是,我通常会尝试将 GET、POST、PUT、DELETE 方法保留给实体,并将 URL 与实体的层次结构相关联。它是否 100% 有效,不,但它是否让任何在我身后的编码人员都很明显,几乎总是答案是肯定的。

在我看来,您的 /documents 与 /user/docs 示例意味着您有两个不同的文档。超出用户寿命的文档和将由用户帐户生存和死亡的文档。如果在我的示例中您有 /documents/usr/id 那么我会说即使您使用 /documents/usr/id “删除”该文档我会说您只是删除该用户引用该文档作为文档在层次结构中高于用户。同样,如果您有 /user/document/id,我会说该文档是特定于用户的,并且会随着用户而死。

希望这是有道理的。再说一次,并不是说我是 100% 正确的,而且总是有特殊情况。

【讨论】:

【参考方案3】:

我在这里没有看到任何问题。 REST 没有 URI 约束,这是一个实现细节,完全取决于服务开发人员。

REST 是关于 M2M 通信而不是 H2M 通信,因此最终用户不会看到任何关于 REST URI 的信息。

如果您应用 HATEOAS 约束,客户端也不关心 URI。如果您不喜欢超媒体响应而更愿意记录 URI 模板,那么我认为较短的 URI 更好,因为客户端开发人员更容易误输入。

关闭:

我目前正在阅读 Vernon 的书中关于 DDD 聚合的内容,这里有一个有趣的相似之处。如果您想访问用户文档,那么您有 2 个建模选项。

第一个选项将文档放在用户聚合后面,所以你必须使用user1 = userRepo.findById(1); user1docs = user1.documents 使用用户聚合来访问它们。 定义文档聚合的第二个选项:user1docs = docRepo.findByUserId(1)

这有点类似于users/1/docs vs docs?user=1

通过 DDD,解决方案取决于业务需求。如果您在某些情况下需要用户与其文档之间的事务(即时)一致性,那么第一个是不错的选择,否则您可以坚持最终一致性和第二个选项。 也许这也可以应用于 REST。因此,如果文档和用户属性之间存在不变量,那么您必须使用

PUT /users/1 
    prop: 123,
    docs: [
        ,
        ,
        ...
    ]

以避免不一致的状态。否则最好坚持以下几点:

PUT /users/1 
    prop:123


POST /docs/ [
    ,
    ,
    
]

POST /user-docs/ [
    user:1, doc: 1,
    ,
    ,
    ...
]

很难找到任何同时依赖于用户属性和用户文档的验证规则,所以我可能会选择第二个选项。

办公室。此规则可能存在例外情况,例如,如果第二个选项速度慢得令人无法接受,或者您想轻松地将用户文档添加到客户端的开发人员,那么最好使用第一个选项。

【讨论】:

RESTful API 设计:url 参数应该有默认值吗?

】RESTfulAPI设计:url参数应该有默认值吗?【英文标题】:RESTfulAPIdesign:Shouldurlparametershavedefaultvalues?【发布时间】:2018-09-0108:20:02【问题描述】:在设计HTTPRESTfulAPI时,是否可以在省略参数时使用默认值?还是那令人困惑?例如:... 查看详情

API 设计 - 最好为客户和我们的 Web 应用程序运行共享 api,还是将其拆分为 2 个 api,私有和公共?

】API设计-最好为客户和我们的Web应用程序运行共享api,还是将其拆分为2个api,私有和公共?【英文标题】:APIDesign-Woulditbebesttorunasharedapiforcustomersandourwebapporsplititinto2apis,privateandpublic?【发布时间】:2014-05-1611:58:18【问题描述】... 查看详情

restful接口设计规范(代码片段)

目录1.协议API与用户的通信协议,尽量使用HTTPs协议2.域名应尽量将API部署在专用域名之下https://api.example.com如果API很简单,不会有进一步扩展,可以考虑放在主域名之下https://example.org/api/3.版本应将API的版本号放入URL... 查看详情

使用 RESTful 服务保护跨域的 API 调用

】使用RESTful服务保护跨域的API调用【英文标题】:SecuringAPIcallsfromcrossdomainusingRESTfulservice【发布时间】:2017-06-0400:37:03【问题描述】:我有一个预订网站,我从该网站向用户提供几行代码,并在其中将API密钥与代码一起添加到div... 查看详情

RESTful API - 设计子资源

】RESTfulAPI-设计子资源【英文标题】:RESTfulAPI-Designingsub-resources【发布时间】:2016-10-1314:25:06【问题描述】:我正在设计一个RESTfulAPI,但遇到了与子资源相关的问题。我看到其他API使用完整URL来操作子资源。以CompanyhasDepartments和... 查看详情

restful规范(代码片段)

一、关于RESTfulREST与技术无关,代表的是一种软件架构风格,REST是RepresentationalStateTransfer的简称,中文翻译为“表征状态转移”;REST从资源的角度类审视整个网络,它将分布在网络中某个节点的资源通过URL进行标识,客户端应用... 查看详情

restful设计理论

RESTful设计:1.协议通信协议:https2.域名部署在API专用域名下,除非API很简单(https://www.example.com/api)https://api.example.com 3.版本应将版本号放在url中(.../v1/...);也可以放在http头中 4.路径不能有动词,只能有名词;所用名... 查看详情

RESTful API 设计 - 使用资源 URI 与 ID

】RESTfulAPI设计-使用资源URI与ID【英文标题】:RESTfulAPIdesign-usingaresourceURIvsanID【发布时间】:2021-09-3010:02:04【问题描述】:这是我的第一篇文章,所以请多多包涵。我正在设计一个新的RESTfulAPI,在我的客户如何与他们创建的资源... 查看详情

restful-5开发api(代码片段)

RESTful 是目前最流行的API设计规范,用于Web数据接口的设计。它的大原则容易把握,但是细节不容易做对。本文总结RESTful的设计细节,介绍如何设计出易于理解和使用的API。一、URL设计1.1动词+宾语RESTful的核心思想就是,客... 查看详情

如何拥有与公共数组成员关联的私有数据?

...述】:我正在用C#开发一个游戏,但我对正确的面向对象设计有点困惑。游戏中有3D空间中的节点:publicclassNodepublicVector3Position;publicVector3Size;//etc然后, 查看详情

restful接口设计规范(代码片段)

restful接口设计规范1.域名应该尽量将API部署在专用域名之下。https://api.example.com如果确定API很简单,不会有进一步扩展,可以考虑放在主域名下。https://www.example.org/api/2.版本(Versioning)应该将API的版本号放入URL。http://www.example.co... 查看详情

Laravel RESTful API 版本控制设计

】LaravelRESTfulAPI版本控制设计【英文标题】:LaravelRESTfulAPIversioningdesign【发布时间】:2015-07-2605:11:45【问题描述】:我是Laravel(4和5)的新手,最近一直在研究RESTfulAPI。为了允许API的多个版本,我使用URL来确定版本。似乎大多数... 查看详情

restful接口设计

URL设计规范:/模块/资源/{标示}/集合1/...eg:  /user/{uid}/friends  ->好友列表例子:秒杀系统API设计  查看详情

如何将 flask.url_for() 与 flask-restful 一起使用?

】如何将flask.url_for()与flask-restful一起使用?【英文标题】:HowdoIuseflask.url_for()withflask-restful?【发布时间】:2014-08-0502:15:11【问题描述】:我已经像这样设置了Flaskrestful:api=Api(app,decorators=[csrf_protect.exempt])api.add_resource(FTRecordsAPI,\'... 查看详情

restful接口设计规范(代码片段)

1.域名1应该尽量将API部署在专用域名之下.https://api.example.com2如果确定API很简单,不会有进一步扩展,可以考虑放在主域名下.https://example.org/api/2.版本(Versioning)1第一种将API的版本号放入URL.http://www.example.com/app/1.0/foohttp://www.example.com/a... 查看详情

restful规范(代码片段)

一什么是RESTful二 RESTfulAPI设计三基于Django实现回到目录一什么是RESTfulREST与技术无关,代表的是一种软件架构风格,REST是RepresentationalStateTransfer的简称,中文翻译为“表征状态转移”REST从资源的角度类审视整个网络,它将分... 查看详情

drf完整版(代码片段)

1.restful规范概述:1.RESTful是目前最流行的API设计规范,用于Web数据接口的设计。代表的是一种软件架构风格。它将分布在网络中某个节点的资源通过URL进行标识,客户端应用通过URL来获取资源的表征,获得这些表征致使这些应用... 查看详情

RESTful API 设计 - /users/:userId/resourceType 与 /resourceType/?user=:userId

】RESTfulAPI设计-/users/:userId/resourceType与/resourceType/?user=:userId【英文标题】:RESTfulAPIdesign-/users/:userId/resourceTypevs./resourceType/?user=:userId【发布时间】:2013-07-2515:52:25【问题描述】:我正在旋转我的轮胎,我很想知道其他人在相同情... 查看详情