hdpe / bowman

A Java library for accessing a JSON+HAL REST API
Apache License 2.0
47 stars 18 forks source link

Support for _embedded resources #39

Open SimonBodner opened 3 years ago

SimonBodner commented 3 years ago

Hi!

Is there any way to add embedded resources (_embedded property in HAL) to a bowman model? I did not find a way to do that yet. If it's not supported by bowman (yet), are there any plans to add this feature to the library in future? I think it should be something similar than the annotations for linked resources (@LinkedResource), e.g. defining an embedded resource by using an annotation @EmbeddedResource.

Thanks in advance.

hdpe commented 3 years ago

Hi,

Not sure if you found this but the embedded resources section in the docs is pretty to-the-point on the matter:

Subresources are loaded from the _embedded property of a HAL response when querying a collection resource. For single-valued resources, embedded resources are currently disregarded: PRs welcome!

...which is probably not what you want to hear.

However, I did make a bit of progress on this (three years ago...) which never got fully integrated as it involved using some poorly documented Jackson APIs to get around some unexpected behaviour in Spring HATEOAS, but this might be sufficient for your needs.

Take a look at 599b3a895ce412698a7a4929a7365d4e3fb12f9f in the branch hal-resources-deserializer-mod -- it seems with this you can do something like:

    private List<PageableEntity> content;

    @JsonProperty("_embedded")
    @JsonDeserialize(
        using = HalResourcesDeserializer.class,
        contentUsing = InlineAssociationDeserializer.class,
        contentAs = PageableEntity.class)
    public List<PageableEntity> getContent() {
        return content;
    }

to provide your own model for the _embedded property. Note this will only get you as far as reading from an _embedded value (I'm not sure what writing to one would even mean...)

This commit basically brings Spring HATEOAS's HalResourcesDeserializer into Bowman making the necessary changes for this to work that I refer to in this issue I raised upstream that I haven't found the time to resolve.

Would be interested to hear if you can make this work for your use case. If it does, I certainly agree that an @EmbeddedResource annotation would be much much clearer, and maybe we just decide to incorporate this commit into master and consider PRs creating some meta-annotation that makes this messy config go away.

hdpe commented 3 years ago

Bit more context in https://github.com/BlackPepperSoftware/bowman/issues/23#issuecomment-399772235 -- this was my proposed plan to get Spring Data REST paginated APIs working with Bowman, for which sorting out the _embedded situation is a prerequisite.

SimonBodner commented 3 years ago

Thank you for the quick and detailed answer! I'll try it out and try to make it work for my needs, respectively, and give you an update on this as soon as I know more.

SimonBodner commented 3 years ago

Hi @hdpe,

great news: It works for my needs with your provided class and the code snippet!

I am now requesting the embedded resource as you suggested in your first comment. I don't know what it would mean to request the whole data of the embedded resource (to "download" the whole resource) - I just need the links which are contained in the embedded resource (as URLs).

By the way: to get the links (and not to follow the links) which are contained in the embedded resource I request them in a similar way as the embedded resource itself - by providing my own model and the again using the annotations @JsonProperty (but with _links instead of _embedded) and @JsonDeserialize.

hdpe commented 3 years ago

Thanks @SimonBodner for this useful feedback. Glad you got it working - think we should leave this open and as documentation until we can get that commit merged.