如何通过REST和JAX-RS为父子实体建模 [英] How to model parent-child entities via REST and JAX-RS

查看:78
本文介绍了如何通过REST和JAX-RS为父子实体建模的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在基于REST的API上工作,在弄清楚代表父母/孩子关系的规范方法时遇到了一些麻烦. (我正在用CXF编写bean,并使用JAX-RS和JAXB.我从CXF提供的基本示例开始)

我的问题是,假设您有一个Foo和一个Bar. Foo和Bar之间存在1-N关系,即1 Foo有很多Bar.我的问题是,找出Foo有哪些Bars的规范方法是什么?而访问Foo拥有的Bar资源的规范方法是什么?

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

获取 http://xxx/fooservice/foos

并在以下位置对单个foo进行操作:

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

但是如何列出Foo 121拥有的酒吧?以及我如何访问它们?我注意到默认的JAXB marshaller似乎不只输出bean的Collections属性,所以如果Foo是:

Foo
  - String id
  - String name
  - Collection bars

JAXB输出类似:

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

这是有问题的,因为无法合理地期望客户知道Foo有Bars,除非它只是知道"(这对我来说似乎很糟糕).因此,虽然我可以想象使用以下方法获得酒吧的清单:

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

如果实体的输出未提及任何内容,客户如何知道Foo有Bars?现在假设客户端确实获得了列表,那么似乎实体操作将类似于:

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

它将访问Foo 121拥有的Bar435.

解决方案

您想做的事情肯定是可能的.设计资源的一种方法是:

/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's Bars,您将获取Foo,修改Foo表示中的Bars,然后放入Foo.

不确定序列化的XML表示怎么回事,您应该使用相关代码创建第二个问题.

I am working on a REST based API, and having some trouble figuring out what the canonical way is to represent parent / child relationships. (I am writing beans in CXF and using JAX-RS and JAXB. I started from the basic example provided by CXF)

My problem is let's say you have a Foo and a Bar. There is a 1-N relationship with Foo and Bar, that is 1 Foo has many Bars. My question is, what's the canonical way to find out what Bars a Foo has? And what's the canonical way to access Bar resources owned by the Foo?

I have figured out that for example I might list Foos at:

GET http://xxx/fooservice/foos

And operate on a single foo at:

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

But how do I list Bars that Foo 121 has? And how do I access them? I've noticed that it seems the default JAXB marshaller doesn't output Collections just attributes for a bean, so if a Foo is:

Foo
  - String id
  - String name
  - Collection bars

JAXB outputs something like:

<foo><id>123>/id><name>foo name</name></foo> <-- note the absence of the bars attribute

Which is problematic, as there is no way for the client to reasonably be expected to know that Foo has Bars, unless it "just knows" (which seems bad to me). So while I can imagine to get a list of bars using:

GET http://xxx/fooservice/foo/121/bars

How does a client know that Foo has Bars if the output of the entity doesn't say anything about it? Now presuming the client does get the list, then it seems entity operations would be something like:

GET/DELETE/UPDATE http://xxx/fooservice/foo/121/bar/435

which would access Bar 435 owned by Foo 121.

解决方案

What you want to do is certainly possible. One way of designing the resources is:

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

You may have a situation where the Bars have no real existence outside of a particular Foo (as in a purchase order's master and the detail rows it contains). If this is the case, and each Foo hasn't got all that much Bar data to go with it, you could return the full Bar details right in the Foo representation:

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

You generally want coarser granularity with REST resources. Note that if you choose this, then to modify a Foo's Bars, you'd GET the Foo, modify the Bars in the Foo representation, and then PUT the Foo.

Not sure what's happening with your serialized XML representations, you should create a second question with the relevant code.

这篇关于如何通过REST和JAX-RS为父子实体建模的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆