【问题标题】:REST resource related dataREST 资源相关数据
【发布时间】:2014-01-05 22:50:46
【问题描述】:

我创建了一个 REST API,但我认为我遇到了一个 RESTful 问题。

与以下问题有关:

我有一个名为“案例”的资源。案例还具有相关数据,例如用户和消息。 问题是我想从一个案例中获取相关的查询用户和消息数据,但我不确定 URI 设计。还有不同种类的相关/计算数据。这些相关数据应该用于创建数据可视化。

我如何获得案例/用户/消息是 RESTful:

http://example.com/cases (and with id for a single case)
http://example.com/cases/{id}/users (same idea as above)
http://example.com/cases/{id}/messages (same idea as above)

我创建相关资源的第一个想法是(我认为 URI 看起来不对,可能有点 RPC?):

相关资料1:

http://example.com/cases/{id}/analysis/messages-network-traffic

{
    "sender": "an user jack", 
    "receiver": "an user steph", 
    "amount_messages": 51
}, 
{
    "sender": "an user test", 
    "receiver": "an user test4", 
    "amount_messages": 3
}
...

相关资料2:

http://example.com/cases/{id}/analysis/messages-timeline?receiver=testuser1&sender=testuser2
{
    "amount_messages": 24, 
    "timestamp": 1387321576
}, 
{
    "amount_messages": 50, 
    "timestamp": 1387321576
}
...

这些是对 URI 设计的正确思考(我认为这是一种 RPC),或者我应该怎么做? 因为我看不出有任何理由像相关问题一样创建报告资源。数据只是对现有资源的计算。

提前谢谢你。

【问题讨论】:

    标签: rest restful-url restful-architecture


    【解决方案1】:

    仅仅因为你可以提供一个实现并不意味着这样做是有意义的。例如,对http://example.com/cases 执行 PUT 可能没有意义。你会 PUT 改为http://example.com/cases/1 或类似的东西。一个具体的例子。同样,在http://example.com/cases/1 上执行 POST 也可能没有意义。使用 REST 语法由您决定应用程序的语义。

    我认为您的 REST 设计没有任何问题 - 只要端点以“声明性”方式命名,就可以了。如果他们有一些“程序”名称,例如:http://example.com/cases/goDoSomething,那将引起关注。

    请记住,您的 REST 设计是您的客户用来与您的服务对话的“语言”,因此请设计该语言以使沟通具有声明性并适合手头的任务。为用户设计,而不是在后端为您自己的方便而设计。

    【讨论】:

      【解决方案2】:

      我知道你已经在这里接受了一个答案,但我觉得这两个答案都有点偏离目标。

      为您的问题设计一个 RESTful 解决方案与您的 URL 的外观无关,而 一切与提供关系链接作为表示本身的一部分。您需要使用允许您表达这些链接关系的媒体类型。 HTML 可以,但 XML 和 JSON 本身不会。我个人最喜欢的是 HAL over JSON。

      这是您的示例在 JSON 上使用 HAL 时的样子:

      请求:

      GET /cases/1 HTTP/1.1
      Host: example.com
      

      回应:

      HTTP/1.1 200 OK
      Content-Type: application/hal+json;profile=vnd/com.example-v1
      
      {
        _links: {
          "self": {
            href: "/cases/1"
          },
          "users": {
            href: "/cases/1/users"
          },
          "newest_user": {
            href: "/users/371629"
          },
          "messages": {
            href: "/cases/1/messages"
          }
        },
        "case-name": "Foo",
        "case-created-date": "2013-11-01"
        ..... <more case attributes here>
      } 
      

      请注意,指向“newest_user”的链接指向单个用户,并且该引用是不透明的(即,如果没有服务器为您提供该值,您将无法猜到它)。从技术上讲,在这样的架构中,所有 URL 都应该被视为不透明的(即使其中一些是人类可读的并且以 resource/id/subresource 之类的方式组织)。

      因此,当您编写 API 指南时,您可以指定每个链接关系的含义(在这种情况下,用户、最新用户和消息),并且客户端将知道他们在访问每个链接时会得到什么,不管 URL 是什么样的

      顺便说一句,这种类型的信息在 REST 世界中被称为“作为应用程序状态引擎的超媒体”,也称为“超媒体约束”。这是REST统一接口约束的要求。

      【讨论】:

        【解决方案3】:

        您的这些网址看起来不错:

        http://example.com/cases(以及单个案例的 id)

        http://example.com/cases/{id}/users(同上)

        http://example.com/cases/{id}/messages(同上)

        就您的相关数据以及如何查询它们而言,我建议您首先决定返回数据结构,考虑到在这两种情况下您都返回“消息”(尽管包含一些不同数据)。我要做的是,我将为这两个相关资源 url 提供一个通用的 json 结构,类似于

        {"sender": "一个用户测试",

        "receiver": "an user test4",

        “amount_messages”:3,

        “时间戳”:12312421424}

        我的资源网址看起来有点像这样:

        GET http://example.com/cases/{id}/messages

        GET http://example.com/cases/{id}/messages?receiver=testuser1&sender=testuser2

        我不明白网址中出现“/分析”的原因。它有点多余(除非有一个非常具体的原因)。将使用您的 api 的客户期望返回数据是通用的,尤其是当他们尝试对同一资源进行过滤查询时。在您的情况下,我们要么列出“消息流量”(我称之为列出“所有消息”),要么列出“消息流量”,其中发送者是 FOO,接收者是 BAR(我称之为过滤“所有消息”数据)发送方和接收方信息。

        保持返回数据模型一致有助于客户端开发人员生成 POJO(在 Java 领域)和/或在他们这边也生成一致的数据模型。

        我希望这会有所帮助!祝你好运!

        【讨论】:

        • 我的例子是关于消息的,但是它可以返回一个“案例”的相关资源的所有相关计算数据。所有这些计算的数据结果都尽可能通用,但结果旨在创建分析工具(如图形和东西)。对于每种图形样式,他们都需要另一个结果。这就是为什么我通过以下方式将每个案例分开:/analysis/a-graph-data-result-style
        • 这就是重点,你不应该这样做。正如史蒂夫上面提到的,网址不应该是声明性的。如果您希望您的返回类型与图形样式相关,您也可以有这样的东西:GET example.com/analysis{graph-style}/cases/{id}/messages?receiver=testuser1&sender=testuser2 查看 urls 客户端可以很容易确定数据模型可能不会改变(这里的数据格式总是“消息”的格式),但数据本身会根据他们要求数据的图形样式而改变。
        • 但是在大​​多数情况下,作为服务提供者,您不应该担心客户端正在实现什么样的图形样式。 Facebook/Google 可能有大量由客户开发的应用程序,每个应用程序都实现了自己的一组图表(当然取决于用例)。如果他们开始为每个客户端提供图形样式的自定义数据,那对任何服务提供商来说都没有意义。
        • 这是一个很好的观点。所以我在想当我想从消息中获取计算数据时 URL 应该是什么样子。其中一种可能性是让客户端通过获取所有消息来计算此数据:example.com/cases/{id}/messages,然后计算到我想要的结果集(如我的示例)。实际上,这对客户端来说可能很重。那么进行 RESTful 查询以获取具有属性“sender”、“receiver”、“amount_messages”的结果集的最佳解决方案是什么?数据对象包括“案例”内的所有发送方/接收方组合(带有数量消息)。
        • 我想我不明白你的担心。如果你想自己处理计算这些数据的逻辑,你仍然可以。您的计算和逻辑处理与您设计/构造的 REST url 无关。他们都是完全独立的。这是您的客户如何知道 url 是什么的问题(使用我上面提到的 url 设计)
        猜你喜欢
        • 1970-01-01
        • 2019-12-23
        • 1970-01-01
        • 2016-07-14
        • 2016-11-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-18
        相关资源
        最近更新 更多