我们有一个Java服务器Web应用程序,其中系统的核心包含一个非常复杂的领域模型,它是根据领域驱动设计的原则设计的。在大多数情况下,这些领域对象对其他关注的应用程序影响很小。如何最好地在XML中为HATEOAS实现链接关系?
我们现在正在考虑在系统前放置一个REST Web服务API,并且我正在努力如何最好地实现我们自己的新媒体类型中的HATEOAS链接。例如,让我们说,我们有与JAX-B上的注释的ID和name属性域类foo
:
@XmlType(name = "foo")
public class FooImpl implements Foo {
private String name;
private String id;
...snip....
@XmlID
@XmlAttribute
@Override
public String getId() {
return id;
}
@XmlElement
@Override
public String getName() {
return name;
}
@Override
public void setName(final String name) {
this.name = name;
}
}
但我想回到看起来像这样的XML:
<foo id="123" href="http://myserver.com/foos/123">
<name>myFoo</name>
<links>
<link rel="previous" href="http://myserver.com/foos/122" type="application/mything+xml" />
<link rel="next" href="http://myserver.com/foos/124" type="application/mything+xml" />
<link rel="edit" href="http://myserver.com/foos/123" type="application/mything+xml" />
<link rel="revise" href="http://myserver.com/foos/123" method="put" type="application/mything+xml" />
<link rel="cancel" href="http://myserver.com/foos/123?op="cancel"" method="post" type="application/mything+xml" />
</links>
</foo>
是什么这样做的最佳方式是,我没有污染我的域设计与这些媒体类型链接,但是仍然可以使用JAX-B用于XML编组的功能?这里有一些想法:
1)JAX-B适配器 - 我可以使用这些来修改实体的XML和插入链接..它有可能吗?这是否合理?任何例子?
2)DTO层 - 创建一个新的REST服务层,将DTO中的域对象转换。到目前为止,我们能够避免DTO的麻烦。虽然这将为我们返回客户端提供全面的灵活性,但我也不打算在此创建域不可知的客户端。
3)Link Headers - 我真的很喜欢这个想法,但我认为它不会工作(本身),因为我们的资源有时包含子资源的集合。在这种情况下,子资源仍然必须编组为XML,其中包含链接/ hrefs等。因此,链接标题将问题解决为顶级类型时,它不能解决整个问题。随意否则!
是否有另一种方法可以帮助我避免DTO,但对域模型保持透明?
向模型添加链接需要扩展你的域类,但是你的DAO层不能实例化这些对象。考虑聚合并将JAXB(或任何XML映射)添加到该层。 – 2012-01-16 20:17:00
如果我明白,创建一个REST模型,将链接聚合到域对象并发送。有点像DTO,但更像是扩展域以包含链接。我明白吗? – HDave 2012-01-17 03:44:45
是的,我会创建包装。如有必要,将调用委托给DAO对象。所以基本上这是[装饰设计模式](http://en.wikipedia.org/wiki/Decorator_pattern)。 – 2012-01-17 17:59:17