web-services - RESTful URL 设计 : public vs private API, 层次结构 API 设计模式,URI 与 URL 设计?

标签 web-services api rest restful-url

我经常遇到这样的问题,与 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。

人们如何看待这些问题?

最佳答案

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

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

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

user/{name}/documents

说得通。他们有上下文。

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

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

你提出了一个有趣的例子,它非常清楚地表明了这一点。拿
document/iddocument/name 相比

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

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

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

关于web-services - RESTful URL 设计 : public vs private API, 层次结构 API 设计模式,URI 与 URL 设计?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20693361/

相关文章:

rest - GrailsView解析jsonApi发布数据-Grails团队是否在jsonViews中执行通用解决方案?

java - 如何在 JAX-WS 中添加响应 header

ios - 从返回 SIGABRT 的 Web 服务访问字典对象

javascript - 如何在 while 循环中仅显示一次文本?

c# - 按 ID 或按类型和语言更新资源的 RESTful 约定

ruby-on-rails - 如何更改 activeresource ruby​​ gem 中的请求 url 结构

jquery - 如何从 native Android 2.1 浏览器使用 javaScript 检查与服务器的连接?

java - 使用JAVA解析SOAP响应并提取特定节点

python - Django、Borg 模式、API 调用、缓存结果

api - 使用 Postman 和 Jetpack 测试 API 速率限制