如何通过 REST 和 JAX-RS 建模父子实体
我正在开发基于 REST 的 API,但在弄清楚表示父/子关系的规范方法时遇到了一些麻烦。 (我正在 CXF 中编写 beans,并使用 JAX-RS 和 JAXB。我从 CXF 提供的基本示例开始)
我的问题是,假设您有一个 Foo 和一个 Bar。 Foo和Bar之间存在1-N关系,即1个Foo有多个Bar。我的问题是,找出 Bars a Foo 有什么的规范方法是什么?访问 Foo 拥有的 Bar 资源的规范方法是什么?
我发现,例如我可以在以下位置列出 Foos:
GET http://xxx/fooservice/foos
并且对单个 foo 进行操作:
PUT/UPDATE/DELETE http://xxx/fooservice/foo/{但是
我如何列出 Foo 121 拥有的 Bars?我如何访问它们?我注意到默认的 JAXB 编组器似乎不输出 Collections 只是 bean 的属性,因此如果 Foo 是:
Foo - String id - String name - Collection bars
JAXB 输出类似:
这是有问题的,因为客户端无法合理地期望知道Foo有Bars,除非它“只是知道”(这对我来说似乎很糟糕)。因此,虽然我可以想象使用以下方法获取酒吧列表:
GET http://xxx/fooservice/foo/ 121/bars
如果实体的输出没有说明任何内容,那么客户端如何知道 Foo 有 Bars?现在假设客户端确实获取了列表,那么实体操作似乎类似于:
GET/DELETE/UPDATE http://xxx/fooservice/foo/121/bar/435
它将访问 Foo 121 拥有的 Bar 435。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
你想做的事情当然是可能的。设计资源的一种方法是:
您可能会遇到这样的情况,即 Bars 在特定 Foo 之外并不真正存在(如在采购订单的主数据及其包含的详细信息行中)。如果是这种情况,并且每个 Foo 没有获得那么多的 Bar 数据,您可以在 Foo 表示中返回完整的 Bar 详细信息:
您通常希望 REST 资源具有更粗的粒度。请注意,如果您选择此选项,那么要修改 Foo 的 Bars,您需要获取 Foo,修改 Foo 表示形式中的 Bars,然后 PUT Foo。
不确定序列化的 XML 表示发生了什么,您应该使用相关代码创建第二个问题。
What you want to do is certainly possible. One way of designing the resources is:
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:
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.
感谢您详细的帖子 - 您所描述的基本上已经是我正在做的事情,而没有按照您的建议对每个 Foo 内的 Bars 进行详细表示,所以看来我的大部分都是正确的。
我将找出为什么 Foo 内的 Bars 集合没有按照您的建议在单独的 Q 中以 JAXB 中的 XML 形式解组。
Thanks for the detailed post - what you describe is basically already what I am doing without the detailed representation of Bars inside each Foo as you suggest so it seems I had it mostly right.
I will find out why the Collection of Bars inside a Foo is not getting unmarshalled as XML in JAXB in a separate Q as you suggest.
Taylor, Jersey 的 JAX-RS 实现确实发出了转换为 XML 或 JSON 的对象的 List 属性。因此,在我刚刚完成的应用程序中,UserStore 对象有一个属性 users,这是一个列表:
当我使用 Jersey 发出 UserStore 的 XML 或 JSON 版本时,我会得到该属性的用户数组:
也许
是问题你遇到的只是与你的财产是一个集合而不是一个列表有关......
Taylor, Jersey's implementation of JAX-RS certainly does emit the List properties of objects that it converts into XML or JSON. So in an app I just finished, the UserStore object has a property, users, that's a List:
When I use Jersey to emit the XML or JSON version of the UserStore, I get an array of users for that property:
and
Perhaps the issue you're running into is merely related to your property being a Collection rather than a List...
对我来说,这个问题的答案将由数据建模驱动,对于数据建模,问题是“是否为子模型使用复合键”(如果他使用复合键),因此如果没有使用复合键,则必须将父 ID 放入 URI 中,并且孩子有自己的 id,它不是复合的,因此您可以仅使用带有孩子 id 的 URL。
所以这是数据建模问题!
for me this question answer is going to be driven by data modeling, and for data modeling the question is "using composite key for child model or not" if he is using composite key so you have to put the parent id in URI if not and child have its own id which is not composite so you can just use URL with child id only.
so this is data modeling question!!!