【问题标题】:How to model parent-child entities via REST and JAX-RS如何通过 REST 和 JAX-RS 对父子实体进行建模
【发布时间】:2013-09-04 23:13:41
【问题描述】:

我正在开发基于 REST 的 API,但在弄清楚表示父/子关系的规范方法时遇到了一些麻烦。 (我在CXF中写bean,使用JAX-RS和JAXB。我从CXF提供的基本示例开始)

我的问题是假设您有一个 Foo 和一个 Bar。 Foo 和 Bar 存在 1-N 关系,即 1 Foo 有许多 Bars。我的问题是,找出 Bars a Foo 有什么的规范方法是什么?访问 Foo 拥有的 Bar 资源的规范方法是什么?

我发现例如我可以在以下位置列出 Foos:

获取http://xxx/fooservice/foos

并在单个 foo 上操作:

PUT/UPDATE/DELETE http://xxx/fooservice/foo/{fooid}

但是我如何列出 Foo 121 拥有的 Bars?我如何访问它们?我注意到默认的 JAXB 编组器似乎不输出集合只是 bean 的属性,所以如果 Foo 是:

富 - 字符串 ID - 字符串名称 - 收藏酒吧

JAXB 输出类似:

123>/id>foo name

这是有问题的,因为无法合理地期望客户知道 Foo 有 Bars,除非它“只是知道”(这对我来说似乎很糟糕)。因此,虽然我可以想象使用以下方法获取条形列表:

获取http://xxx/fooservice/foo/121/bars

如果实体的输出没有说明,客户如何知道 Foo 有 Bars?现在假设客户端确实获得了列表,那么实体操作似乎是这样的:

获取/删除/更新http://xxx/fooservice/foo/121/bar/435

这将访问 Foo 121 拥有的 Bar 435。

【问题讨论】:

    标签: rest jax-rs


    【解决方案1】:

    你想做的当然是可能的。设计资源的一种方法是:

    /foo
              # A list of all the Foo resource names (not representations).
    
    /foo/{fooid}
              # A detailed representation of a particular Foo, including 
              # a list of all that Foo's Bar resource names (not representations).
    
    /foo/{fooid}/bar/{barid}
              # A detailed representation of a particular Bar.
    

    您可能会遇到 Bars 在特定 Foo 之外没有实际存在的情况(例如在采购订单的主数据行及其包含的明细行中)。如果是这种情况,并且每个 Foo 没有获得那么多 Bar 数据,您可以在 Foo 表示中返回完整的 Bar 详细信息:

    /foo
              # A list of all the Foo resource names (not representations).
    
    /foo/{fooid}
              # A detailed representation of a particular Foo, including 
              #   full details on each of its Bars.
    

    您通常希望 REST 资源的粒度更粗。请注意,如果您选择此选项,那么要修改 Foo 的 Bars,您需要获取 Foo,修改 Foo 表示中的 Bars,然后 PUT Foo。

    不确定您的序列化 XML 表示发生了什么,您应该使用相关代码创建第二个问题。

    【讨论】:

      【解决方案2】:

      感谢您提供详细的帖子-您所描述的基本上已经是我正在做的事情,而没有您建议的每个 Foo 中的 Bars 的详细表示,所以看来我基本上是正确的。

      我将找出为什么 Foo 中的 Bars 集合没有按照您的建议在单独的 Q 中的 JAXB 中解组为 XML。

      【讨论】:

        【解决方案3】:

        Taylor,Jersey 的 JAX-RS 实现确实会发出对象的 List 属性,并将其转换为 XML 或 JSON。所以在我刚刚完成的一个应用程序中,UserStore 对象有一个属性 users,它是一个 List:

        List<User> users = new ArrayList<User>();
        

        当我使用 Jersey 发出 UserStore 的 XML 或 JSON 版本时,我得到了该属性的一组用户:

        <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
        <users>
            <user>
                <firstName>John</firstName>
                <id>a29a377f-4329-4ec8-9459-b5b1c2efc38a</id>
                <lastName>Doe</lastName>
            </user>
            <user>
                <firstName>Jane</firstName>
                <id>bb4dad28-1263-440a-afc5-062a8566ef90</id>
                <lastName>Roe</lastName>
            </user>
        </users>
        

        {
            "user": [{
                "firstName": "John",
                "id": "a29a377f-4329-4ec8-9459-b5b1c2efc38a",
                "lastName": "Doe",
            },
            {
                "firstName": "Jane",
                "id": "bb4dad28-1263-440a-afc5-062a8566ef90",
                "lastName": "Roe",
            }]
        }
        

        也许您遇到的问题仅与您的属性是集合而不是列表有关...

        【讨论】:

          【解决方案4】:

          对我来说,这个问题的答案将由数据建模驱动,对于数据建模,如果他使用复合键,则问题是“是否使用复合键作为子模型”,因此您必须将父 ID 放在 URI 中如果没有,孩子有自己的 id 不是复合的,所以你可以只使用带有孩子 id 的 URL。

          所以这是数据建模问题!!!

          【讨论】:

            猜你喜欢
            • 2013-10-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-02-03
            • 1970-01-01
            • 2011-10-29
            • 1970-01-01
            相关资源
            最近更新 更多