简体   繁体   English

REST HATEOAS:如何序列化嵌套资源(使用Spring HATEOAS)?

[英]REST HATEOAS: How to serialize nested resources (with Spring HATEOAS)?

I use Spring HATEOAS for creating a REST HATEOAS API in my application. 我使用Spring HATEOAS在我的应用程序中创建REST HATEOAS API。 It works well so far, but I'm stuck when it comes to nested resources. 到目前为止,它运行良好,但是在嵌套资源方面我还是很困惑。 What is the right approach for mapping a class hierarchy like this to a REST HATEOAS resource: 将这样的类层次结构映射到REST HATEOAS资源的正确方法是:

public class MyEntity {

    private int id;

    private List<ChildEntity> children;

}


public class ChildEntity {

    private int id;

    private AnotherEntity entity;

}


public class AnotherEntity {
}

I created Resource classes for all of this entities, but when serialising MyEntity, all contained entities get serialized as POJOs although I need them to be serialized as resources too (with links etc). 我为所有这些实体创建了Resource类,但是在序列化MyEntity时,所有包含的实体都被序列化为POJO,尽管我也需要将它们序列化为资源(带有链接等)。 Is there a way to add a resource to a parent resource (and not using the Resources class)? 有没有一种方法可以将资源添加到父资源(而不使用Resources类)? Or do I have to add a @JsonIgnore to children and then manually add the children as resources in my ResourceAssembler ? 还是我必须向孩子添加@JsonIgnore,然后在ResourceAssembler中手动将孩子添加为资源? Wouldnt it then make more sense to use ResourceSupport instead of Resource? 那么使用ResourceSupport而不是Resource更有意义吗?

Extending ResourceSupport: 扩展ResourceSupport:

public class MyEntityResource extends ResourceSupport {

    private int identificator;

    private List<ChildEntityResource> children;

    public int getIdentificator() {
        return identificator;
    }

    public void setIdentificator(int id) {
        this.identificator = identificator;
    }

    public List<ChildEntityResource> getChildren() {
        return children;
    }

    public void setChildren(List<ChildEntityResource> children) {
        this.children = children;
    }

}

public class ChildEntityResource extends ResourceSupport {

    private int identificator;

    private AnotherEntityResource entity;

    public int getIdentificator() {
        return identificator;
    }

    public void setIdentificator(int identificator) {
        this.identificator = identificator;
    }

    public AnotherEntityResource getEntity() {
        return entity;
    }

    public void setEntity(AnotherEntityResource entity) {
        this.entity = entity;
    }
}

public class AnotherEntityResource extends ResourceSupport {

    private String value;


    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}

@RestController
public class EntityController {
    @RequestMapping(value = "/entity", method = RequestMethod.GET)
    public ResponseEntity<MyEntityResource> index() {

        AnotherEntityResource anotherEntityResource  = new AnotherEntityResource();
        anotherEntityResource.add(new Link("link-for-another-entity-resource", "rel-1"));

        anotherEntityResource.setValue("value for Another Entity","rel-2");

        ChildEntityResource childEntityResource = new ChildEntityResource();
        childEntityResource.setIdentificator(20);
        childEntityResource.setEntity(anotherEntityResource);
        childEntityResource.add(new Link("link-for-child-entity-resource", "rel-3"));

        MyEntityResource entityResource = new MyEntityResource();

        entityResource.setIdentificator(100);
        entityResource.setChildren(Arrays.asList(childEntityResource));
        entityResource.add(new Link("link-for-entity-resource"));

        return new ResponseEntity<MyEntityResource>(entityResource,  HttpStatus.OK);
    }

}

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
         SpringApplication.run(Application.class, args);
    }

}

The result is: 结果是:

{
     "identificator": 100,
     "children": [
         {
             "identificator": 20,
             "entity": {
                 "value": "value for Another Entity",
                 "_links": {
                     "rel-1": {
                         "href": "link-for-another-entity-resource"
                    }
                }
            },
            "_links": {
                "rel-2": {
                    "href": "link-for-child-entity-resource"
                } 
            }
        }
    ],
    "_links": {
        "rel-3": {
            "href": "link-for-entity-resource"
        }
    }
}

But you have to consider if this is the right choice to connect different resources. 但是您必须考虑这是否是连接不同资源的正确选择。 Unless you offer in the controller methods get this embedded resources you would not be able the reach them individually. 除非您在控制器中提供方法来获取此嵌入式资源,否则您将无法单独访问它们。 One solution for that is by using HAL. 一种解决方案是使用HAL。 With HAL you can point to a resource by using _links property or embed this resources in the _embedded property. 使用HAL,您可以使用_links属性指向资源,也可以将此资源嵌入_embedded属性。

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

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