Skip to content

Support for Resources in a Resource to be added to _embedded #193

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
tombee opened this issue Jun 5, 2014 · 9 comments
Closed

Support for Resources in a Resource to be added to _embedded #193

tombee opened this issue Jun 5, 2014 · 9 comments
Assignees
Labels
in: core Core parts of the project in: mediatypes Media type related functionality type: enhancement
Milestone

Comments

@tombee
Copy link

tombee commented Jun 5, 2014

After speaking with @olivergierke, we came to the conclusion that there's no way to get a Resources collection added to an _embedded collection in the root of the envelope without using @JsonUnwrapped.

The problem then is that if there are multiple Resources fields, the last field serialized will overwrite the existing _embedded section.

I believe that @olivergierke suggests that a new custom serializer needs to be written to support adding Resources fields to the _embedded section.

@tombee
Copy link
Author

tombee commented Jun 5, 2014

After speaking with @olivergierke further, the current recommended approach can be seen in: https://gist.github.com/olivergierke/697aeab8638084b15604

I think it'd be nice to see a more intuitive way of supporting HAL _embedded resources.

@dschulten
Copy link
Contributor

Do I understand correctly that you want to serialize a bean which has several attributes of type Resources? Could you elaborate why you need this? Resources is meant to be the header for a collection, and the collection "normally" represents the content of the resource. You could then post to that collection, delete from it etc. Having multiple Resources in one response is not the intended usage for a Resource, as I see it right now.
HAL defines that _embedded "values are either a Resource Object or an array of Resource Objects". This should be covered by a Resource of Resources which might contain exactly one or multiple items. I'm curious why this is not sufficient in your case :)

@tombee
Copy link
Author

tombee commented Jun 11, 2014

A use case might be that when I fetch a resource, let's say we are fetching a shop resource, embedded within the resource I would like to add a list of Staff and a list of Products. My instinct was to create a field Resources and a field Resources and hope that the serializer would figure out that both need to be added to _embedded.

What I actually needed to do was to add a field:

@JsonUnwrapped
Resources<Object> _embedded;

To populate it, I needed to combine the elements of the two lists and provide them to the Resources constructor.

It just feels like there might be room for improvement here perhaps? Maybe a HAL specialised version of ResourceSupport could provide some assistance in embedding resources.

I can close the issue if you guys feel that the API is fine as it is, @olivergierke had asked me to create an issue regarding this.

@tombee tombee closed this as completed Mar 30, 2015
@odrotbohm
Copy link
Member

Was this closed by accident?

@tombee tombee reopened this Mar 30, 2015
@tombee
Copy link
Author

tombee commented Mar 30, 2015

Ah I thought it wasn't being addressed, since it's been open for so long without a reply :)

@odrotbohm
Copy link
Member

If we finally decide not to implement it, we can still close it. Currently I am just a bit swamped with other work. :)

@gregturn
Copy link
Contributor

Related to #864

@gregturn
Copy link
Contributor

In #864, I am working on a builder that supports:

@GetMapping("/explicit-and-implicit-rels")
RepresentationModel<?> explicitAndImplicitRelations() {

    Staff staff1 = new Staff("Frodo Baggins", "ring bearer");
    Staff staff2 = new Staff("Bilbo Baggins", "burglar");

    Product product1 = new Product("ring of power", 999.99);
    Product product2 = new Product("Saruman's staff", 9.99);

    return ModelBuilder3 //
            .entity(staff1) //
            .entity(staff2) //
            .entity(product1) //
            .entity(product2) //
            .link(Link.of("/people/alan-watts")) //
            .entity(LinkRelation.of("ring bearers"), staff1) //
            .entity(LinkRelation.of("burglars"), staff2) //
            .link(Link.of("/people/frodo-baggins", LinkRelation.of("frodo"))) //
            .build();
}

Yielding...

{
  "_embedded" : {
    "burglars" : {
      "name" : "Bilbo Baggins",
      "role" : "burglar"
    },
    "staffs" : [ {
      "name" : "Frodo Baggins",
      "role" : "ring bearer"
    }, {
      "name" : "Bilbo Baggins",
      "role" : "burglar"
    } ],
    "ring bearers" : {
      "name" : "Frodo Baggins",
      "role" : "ring bearer"
    },
    "products" : [ {
      "name" : "ring of power",
      "price" : 999.99
    }, {
      "name" : "Saruman's staff",
      "price" : 9.99
    } ]
  },
  "_links" : {
    "self" : {
      "href" : "/people/alan-watts"
    },
    "frodo" : {
      "href" : "/people/frodo-baggins"
    }
  }
}

gregturn added a commit that referenced this issue Apr 17, 2020
Make a fluent API that lets you construct various RepresentationModel objects (EntityModel, CollectionModel, or complex embedded).

Related issue: #193.
gregturn added a commit that referenced this issue Apr 17, 2020
Make a fluent API that lets you construct various RepresentationModel objects (EntityModel, CollectionModel, or complex embedded).

Original pull request: #1273.
Related issue: #193.
gregturn added a commit that referenced this issue Apr 24, 2020
Defines a basic Model.Builder interface that works for all hypermedia types with option for specific mediatypes to implement a customized version.

* Implement a DefaultModelBuilder that only focuses on entities and links. This allows building some of the simplest representations that are supported by all formats.
* Implement a HalModelBuilder that supports the same basic operations but also includes HAL-specific embed() and previewFor() as HAL syntax sugar.

By having a basic interface, other media types are free to either A) go along with the default format, or B) implement their own implementation, with mediatype-specific operators.

Also, introduces a preferredMediaTypes attribute in RepresentationModel so various serializers can warn if the user is attempting to serialize a HAL-specific representation as, say, Collection+JSON.

Original pull request: #1273.
Related issue: #193.
gregturn added a commit that referenced this issue Apr 24, 2020
Defines a basic Model.Builder interface that works for all hypermedia types with option for specific mediatypes to implement a customized version.

* Implement a DefaultModelBuilder that only focuses on entities and links. This allows building some of the simplest representations that are supported by all formats.
* Implement a HalModelBuilder that supports the same basic operations but also includes HAL-specific embed() and previewFor() as HAL syntax sugar.

By having a basic interface, other media types are free to either A) go along with the default format, or B) implement their own implementation, with mediatype-specific operators.

Also, introduces a preferredMediaTypes attribute in RepresentationModel so various serializers can warn if the user is attempting to serialize a HAL-specific representation as, say, Collection+JSON.

Original pull request: #1273.
Related issue: #193.
gregturn added a commit that referenced this issue Apr 24, 2020
…els.

* Implement a `DefaultModelBuilder` that only focuses on entities and links. This allows building some of the simplest representations that are suppoerted by all formats.
* Implement a `HalModelBuilder` that supports the same basic operations but also includes HAL-specific embed() and previewFor() as HAL syntax sugar.

`DefaultModelBuilder` allows defining "simple" formats (single-item or collection at an aggregate root). A `builder()` static helper is provided to create an instance of this type.

`HalModelBuilder` allows going into HAL-specific details, like `embed()` and `previewFor`, where you can specify an entity AND it's link relation. This results in a representation that will generate an "_embedded" entry. It also marks the `RepresntationModel` object with a HAL/HAL-FORMS "preferredMediaType", allowing other serializers to either log warnings, or fail.

Having the interface grants hypermedia authors the ability to create their own customized model builders as they see fit.

Also, introduces a preferredMediaTypes attribute in RepresentationModel so various serializers can warn if the user is attempting to serialize a HAL-specific representation as, say, Collection+JSON.

Original pull request: #1273.
Related issue: #193.
gregturn added a commit that referenced this issue Apr 24, 2020
* Implement a `DefaultModelBuilder` that only focuses on entities and links. This allows building some of the simplest representations that are suppoerted by all formats.
* Implement a `HalModelBuilder` that supports the same basic operations but also includes HAL-specific embed() and previewFor() as HAL syntax sugar.

`DefaultModelBuilder` allows defining "simple" formats (single-item or collection at an aggregate root). A `builder()` static helper is provided to create an instance of this type.

`HalModelBuilder` allows going into HAL-specific details, like `embed()` and `previewFor`, where you can specify an entity AND it's link relation. This results in a representation that will generate an "_embedded" entry. It also marks the `RepresntationModel` object with a HAL/HAL-FORMS "preferredMediaType", allowing other serializers to either log warnings, or fail.

Having the interface grants hypermedia authors the ability to create their own customized model builders as they see fit.

Also, introduces a preferredMediaTypes attribute in RepresentationModel so various serializers can warn if the user is attempting to serialize a HAL-specific representation as, say, Collection+JSON.

Original pull request: #1273.
Related issue: #193.
odrotbohm added a commit that referenced this issue May 7, 2020
HalModelBuilder expose HAL-idiomatic API to set up representations. That includes embeds, previews and syntactic sugar around the inclusion of potentially empty collections as embeds.

Related tickets: #175, #193, #270, #920.
Original pull request: #1273.
@odrotbohm
Copy link
Member

We took a first stab at a HAL specific model builder with 2cab91a. See the updated reference documentation for details.

Feel free to reopen or create a new ticket in case you need additional features.

@odrotbohm odrotbohm added in: core Core parts of the project in: mediatypes Media type related functionality labels May 7, 2020
@odrotbohm odrotbohm self-assigned this May 7, 2020
@odrotbohm odrotbohm added this to the 1.1.0.RELEASE milestone May 7, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Core parts of the project in: mediatypes Media type related functionality type: enhancement
Projects
None yet
Development

No branches or pull requests

4 participants