简体   繁体   English

如何最好地在XML中实现HATEOAS的链接关系?

[英]How best to implement link relations for HATEOAS in XML?

We have a Java server web application where the core of the system contains a very complex domain model that was designed according to the principles of domain driven design. 我们有一个Java服务器Web应用程序,其中系统的核心包含一个非常复杂的域模型,该模型是根据域驱动设计的原则设计的。 For the most part, these domain objects have been affectly very little by the applications other concerns. 在大多数情况下,这些域对象在应用程序的其他问题上影响很小。

We are now looking to put a REST web services API in front of the system and I am struggling with how to best implement the HATEOAS links that come within our own new media type. 我们现在希望在系统前面放置一个REST Web服务API,我正在努力解决如何最好地实现我们自己的新媒体类型中的HATEOAS链接。 For example, lets say we have domain class foo that has an id and name properties with JAX-B annotations: 例如,假设我们有域类foo ,它具有带JAX-B注释的id和name属性:

@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;
    }
}

But the XML I want to return looks like this: 但是我想要返回的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>

What is the best way to do this such that I do not have pollute my domain design with these media type links, but can still use the power of JAX-B for XML marshalling? 最好的方法是什么,这样我没有使用这些媒体类型链接污染我的域设计,但仍然可以使用JAX-B的强大功能进行XML编组? Here are some thoughts: 以下是一些想法:

1) JAX-B Adapters - could I use these to modify the XML for the entities and insert the links..is it possible? 1) JAX-B适配器 - 我可以使用它们来修改实体的XML并插入链接。它可能吗? is it reasonable? 合理吗? Any examples? 任何例子?

2) DTO Layer - Create a new REST service layer that converts my domain objects in DTOs. 2) DTO层 - 创建一个新的REST服务层,用于在DTO中转换我的域对象。 So far we been able to avoid the hassle of DTOs. 到目前为止,我们已经能够避免DTO的麻烦。 While this would provide total flexibility in what we return to the client, I am also not looking to create domain agnostic clients here. 虽然这将为我们返回客户端提供完全的灵活性,但我也不打算在此处创建与域无关的客户端。

3) Link Headers - I really like this idea, but I don't think it would work (by itself) because sometimes our resources contain collections of sub-resources. 3) 链接标题 - 我真的很喜欢这个想法,但我认为它不会起作用(单独使用),因为有时我们的资源包含子资源的集合。 In this case the subresources would still have to be marshalled into XML that contains links/hrefs, etc. So while link headers solves the problem to the top level type, it doesn't solve the entire problem. 在这种情况下,子资源仍然必须编组为包含链接/ hrefs等的XML。因此,虽然链接头解决了顶级类型的问题,但它并不能解决整个问题。 Feel free to say otherwise! 随便说不然!

Is there another approach that will help me avoid DTOs and yet remain transparent to the domain model? 是否有另一种方法可以帮助我避免DTO并对域模型保持透明?

The problem is that correctly generating the links requires knowing the context within which they are being generated, which in turn means that simple JAXB interceptors won't do the job: they simply won't know what URL to insert. 问题是正确生成链接需要知道生成它们的上下文,这反过来意味着简单的JAXB拦截器不会完成这项任务:它们根本不知道要插入什么URL。 What's more, generating the next and previous links will require knowing what those values are; 更重要的是,生成下一个和上一个链接将需要知道这些值是什么; it's probably not safe to say that they are consecutive, as that would imply a resource changing its URL when some other resource is deleted, which would be madness. 说它们是连续的可能是不安全的,因为这意味着当一些其他资源被删除时,资源会改变其URL,这将是疯狂的。

The safest, easiest method is going to be a wrapper class (with JAXB serialization annotations on it) which delegates to the DAO layer for the information it needs. 最安全,最简单的方法是包装类(在其上使用JAXB序列化注释),它将代理到DAO层以获取所需的信息。 While this can be a fair amount of code to write, it's at least easy to get such code right. 虽然这可能是相当多的代码编写,但至少可以很容易地获得这样的代码。 Fancy automated decoration will be much harder. 花哨的自动化装饰将更加困难。

RESTEasy has support for links either via atom or header links. RESTEasy通过原子或头链接支持链接。 There are some extra annotations by which you may point the linked services. 您可以通过一些额外的注释来指向链接的服务。 See chapter 8 of RESTEasy documentation. 请参阅RESTEasy文档的第8章。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM