如何通过REST和JAX-RS为父子实体建模

时间:2009-11-23 23:30:18

标签: rest jax-rs

我正在研究基于REST的API,并且在确定表示父/子关系的规范方法时遇到一些麻烦。 (我在CXF中编写bean并使用JAX-RS和JAXB。我从CXF提供的基本示例开始)

我的问题是让你说你有一个Foo和一个酒吧。与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的条形码呢?我如何访问它们?我注意到,默认的JAXB marshaller似乎不输出集合只是bean的属性,所以如果Foo是:

Foo
  - String id
  - String name
  - Collection bars

JAXB输出如下内容:

< foo>< id> 123> / id>< name> foo name< / name>< / foo> < - 注意没有bars属性

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

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

如果实体的输出没有说明任何内容,客户如何知道Foo有Bars?现在假设客户端确实得到了列表,那么实体操作似乎就像:

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

将访问Foo 121拥有的Bar 435.

4 个答案:

答案 0 :(得分:10)

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

/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.

您可能遇到条形码在特定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表示发生了什么,您应该使用相关代码创建第二个问题。

答案 1 :(得分:0)

感谢你详细的帖子 - 你所描述的内容基本上已经是我正在做的事情,如果你没有详细表示每个Foo里面的条形图,那么看起来我大概都是正确的。

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

答案 2 :(得分:0)

Taylor,Jersey的JAX-RS实现肯定会发出它转换为XML或JSON的对象的List属性。所以在我刚刚完成的应用程序中,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",
    }]
}

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

答案 3 :(得分:0)

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

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