具有RESTful的复杂域URL结构

时间:2014-07-31 08:39:27

标签: rest restful-url

我正在构建一个围绕相当复杂的底层域的RESTful包装器。我使用UML包和类构建了一个域模型,并从有意义的类派生了REST资源。

当谈到endpint-URL设计时,我决定将包/类结构直接映射到URL,以简化流程并在我的逻辑模型(域)和physicall实现(REST API)之间具有整洁的可跟踪性

假设我有以下域提取:

enter image description here

管理员和工作是包,而用户,权限和任务是类(REST资源)。

我从此域派生了以下端点网址:

  • mydomain / admin / user - >用户集合
  • mydomain / admin / user / id - > ID为
  • 的用户实例
  • mydomain / admin / user / id / permissions - >具有id
  • 的用户的所有权限
  • mydomain / work / task ,等等......

我的同事注意到URL不是最佳的,主要是因为这些“包”部分没有映射到具体资源。例如,“admin”不是资源,而是URL的一部分。随着域结构的增长,URL中将存在更多这些中间非资源段,并且他发现它是错误的。

我发现它很好,因为URL结构本身讲述了有关资源的内容,并使用完整的,记录良好的域模型进行备份。

这违反了RESTful标准吗?

3 个答案:

答案 0 :(得分:3)

REST架构没有规定您的URL应该是什么样子。所以,从这个角度来看,你并没有违反任何规则。

相反,REST的一个重要方面是,应该能够使用超链接从一个URL导航到另一个URL(我们在浏览HTML网站时都习惯了这一点,但在REST API中并不常见)。使用链接,您的Web应用程序的消费者(他们是使用Web浏览器的人或使用您的API的其他应用程序)可以发现可用的URL,并且URL的实际结构并不重要。您的网址甚至可以在不破坏其他应用程序的情况下进行更改,因为它们只会链接到新网址的链接。

因此,从REST角度来看,您可以使用您喜欢的任何URL结构。只要您提供固定的入口点以提供指向您的用户集合的链接,实际的URL就可以是任何内容。

但是,当URL易于理解且有些可预测时,它显然仍然有用。例如,您现在拥有带有单一网址( yourdomain / admin / user )的集合和带有多个网址的集合( yourdomain / admin / user / 3 / permissions ) ,这不是很一致。我建议只使用多个名称,因此 yourdomain / admin / user 会变为 yourdomain / admin / users

至于你的实际问题,正如我所提到的,从REST的角度来看,这无关紧要。更重要的是URL清楚地表明它代表什么。我要考虑的是你将要拥有的不同端点的数量。如果您正在使用少量端点构建一个小应用程序,我会保持简单。但是如果你要创建一个包含大量领域模型的非常大的应用程序,那么将它们添加到某些类别中听起来是个好主意。

结论

REST API中的URL应该可以通过超链接发现,因此不存在硬规则。只需确保您的网址对任何需要深入了解的人都有意义。

有关有用网址的一些提示可以在REST-ful URI design

中找到

答案 1 :(得分:3)

  

这违反了RESTful标准吗?

没有。 REST没有关于URL应该如何看的意见。您可以使用类似

的网址
/foo/bar/baz?qux=12

不违反任何REST原则。这样的URL对于人类读者没有意义,但这无关紧要。

没有必要像

这样的网址的每个部分
/foo
/foo/bar

映射到资源。事实上,RESTful URLS必须遵循某种模式或构建规则是一种常见的误解。事实并非如此。

有些常用的最佳做法。其中一种做法是拥有收集资源,如

/mydomain/admin/user

单一资源,如

/mydomain/admin/user/42

但是,再次,REST不需要这样做。

答案 2 :(得分:2)

你没有遵循RESTful的严格定义;但这不是由于你同事的担忧。

您的主要挑战是您的提案已将端点烘焙到客户端应用程序中。寻找用户的客户直接进入 / mydomain / admin / user

但是,如果(以及何时)重新找到该端点,例如 / mydomain / admin / department / user ,您的客户端现在就会崩溃。

解决方案:

REST定义你有一个(或很少)端点,称为"酷URI",它们足够固定,永远不会改变。

而不是您的客户端转到 / mydomain / admin / user 的端点,他们将采用这种方法:

  1. / mydomain (Cool URI)中检索根对象。 => " MYDOMAIN"服务对象。
  2. " MYDOMAIN" object包含一个URI,其标识符为" admin"。遵循该URI。
  3. "管理" object包含一个URI,其标识符为" user"。遵循该URI。
  4. "用户"返回的对象(更可能是用户列表)。
  5. 在这方面,不依赖客户端应用程序必须知道URI格式;因此,当您更改端点时,只需更改服务嵌入在返回的REST对象中的URI。

    这种REST方法,其中每个返回的对象包含下一个的URI,是HATEOAS原则的一部分。

    如果您担心客户如何撤回给定的ID号码(例如用户42),那么也可以提供这样的服务:您可以实施类似OData的服务。同样,URI由父对象提供。而不是客户端使用这样的预烘焙端点:

    • / MYDOMAIN /管理/用户/ 42

    ......而是这样做:

    1. / mydomain (酷URI)
    2. 点击" admin"。
    3. 的链接
    4. 点击"用户"的链接,附加?$ filter = UserId eq 42
    5. 在解决对象版本问题方面也有一些非常好的概念,如果你采用预先对端点进行硬编码的方法,这也很难。

      如果有任何安慰,我开始围绕固定端点定义我的REST架构(就像你一样),然后发现使用真正的RESTful方法从长远来看实际上更简单。

      祝你好运!