Skip to content

@JsonUnwrapped ignored with (embedded) CollectionModel and HAL Forms #968

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
toedter opened this issue Mar 30, 2019 · 6 comments
Closed
Assignees
Labels
in: mediatypes Media type related functionality type: enhancement
Milestone

Comments

@toedter
Copy link

toedter commented Mar 30, 2019

To create REST resources with a list of embedded resources I use a pattern like

@JsonUnwrapped
CollectionModel<EntityModel<Movie>> movies;

As an example:

@Data
public class DirectorRepresentationModel extends RepresentationModel {
    private long id = 1;
    private String name = "Steven Spielberg";

    @JsonUnwrapped
    CollectionModel<EntityModel<Movie>> movies;

    public DirectorRepresentationModel() {
        Movie movie1 = new Movie();
        movie1.setId("1");
        movie1.setTitle("ET");

        Movie movie2 = new Movie();
        movie2.setId("2");
        movie2.setTitle("Jaws");

        EntityModel<Movie> p1 = new EntityModel<>(movie1);
        EntityModel<Movie> p2 = new EntityModel<>(movie2);

        movies = new CollectionModel<>(Arrays.asList(p1, p2));
    }
}

When setting the hypermedia configuration to HAL, it is rendered as I would expect:

{
  id: 1,
  name: "Steven Spielberg",
  _embedded: {
    movieList: [
      {
          id: "1",
          title: "ET"
      },
      {
           id: "2",
           title: "Jaws"
      }
     ]
   }
}

But when setting the hypermedia configuration to HAL_FORMS, the @JsonUnwrapped does not apply:

{
  id: 1,
  name: "Steven Spielberg",
  movies: {
    _embedded: {
       movieList: [
         {
             id: "1",
             title: "ET"
         },
         {
              id: "2",
              title: "Jaws"
         }
        ]
     }
  }
}

IMHO HAL_FORMS should render this exactly like HAL does.

@gregturn
Copy link
Contributor

gregturn commented Mar 30, 2019

HAL-FORMS serialization copies the model’s data into a set of classes aimed at signaling Jackson on how to render. HAL just serializes the Model directly.

I had not anticipated mixing model types like you did. Should make the perfect test case!

Additionally this information is useful for #864.

@toedter
Copy link
Author

toedter commented Mar 31, 2019

Hmm, when using the latest snapshot (March 31.), HAL_FORMS would not render any property in a derived RepresentationModel anymore (at least in my tests). When setting the hypermedia configuration to HAL_FORMS, the above example is now rendered as:

{
  id: 1,
  name: "Steven Spielberg"
}

@gregturn: HAL-FORMS serialization copies the model’s data into a set of classes aimed at signaling Jackson on how to render. HAL just serializes the Model directly.

IMHO it is very important that the HAL_FORMS implementation renders RepresentationModels that don't use any affordances (which will be mapped on HAL Forms _templates) the very same way that the HAL implementation renders them.

Today, the only way I found to get _embedded rendered in a non-collection model with @EnableHypermediaSupport(type = HypermediaType.HAL_FORMS) is to put a _embedded JSON property in the domain model, which is exactly what we want to avoid :)

Or is there a better way using only representation models to render a result with HAL Forms like:

{
  id: 1,
  name: "Steven Spielberg",
  _links: {
    self: {
      href: "http://localhost:8080/directors/4"
    }
  },
  _embedded: {
    movies: [
      {
          id: "1",
          title: "ET"
          _links: {
             self: {
              href: "http://localhost:8080/movies/1"
            }
          }
      },
      {
           id: "2",
           title: "Jaws"
          _links: {
             self: {
              href: "http://localhost:8080/movies/2"
            }
          }
      }
     ]
   }
}

@gregturn
Copy link
Contributor

gregturn commented Mar 31, 2019

IMHO it is very important that the HAL_FORMS implementation renders RepresentationModels that don't use any affordances (which will be mapped on HAL Forms _templates) the very same way that the HAL implementation renders them.

Agreed.

Thought I had a guess what “fix” broke your solution. Turns out I was wrong. My fix hasn’t been merged to master yet.

The point is, HAL and HAL-FORMS use very different serialization strategies so the solution isn’t straight forward.

To be honest I’d like to rewrite HAL so that it’s just like HAL-FORMS offering better consistency in design.

We could almost use a TCK...a batch of tests that exercise a wide range of model combinations with expected outcomes.

@gregturn
Copy link
Contributor

Related to #970.

@toedter
Copy link
Author

toedter commented Apr 6, 2019

A workaround for HAL_FORMS rendering representation model properties is to always use the pattern

public class MyModel extends RepresentationModel<MyModel>

Then all the attributes in MyModel are treated as content.
But still: @JsonUnwrapped would not work for

@JsonUnwrapped
CollectionModel<EntityModel<Movie>> movies;

@gregturn gregturn added this to the 1.0 M3 milestone May 8, 2019
@odrotbohm odrotbohm modified the milestones: 1.0 M3, 1.0 RC1 Jun 13, 2019
@gregturn gregturn modified the milestones: 1.0 RC1, 1.0 RC2 Jul 31, 2019
@gregturn gregturn modified the milestones: 1.0.0.RC2, 1.0.0.RELEASE Sep 5, 2019
@odrotbohm odrotbohm modified the milestones: 1.0.0.RELEASE, 1.1.0.M1 Sep 26, 2019
@odrotbohm odrotbohm modified the milestones: 1.1.0.M1, 1.1.0.M2 Jan 14, 2020
@odrotbohm odrotbohm modified the milestones: 1.1.0.M2, 1.1.0 M3 Feb 11, 2020
@gregturn gregturn modified the milestones: 1.1.0.M3, 1.1.0.M4 Mar 31, 2020
reda-alaoui added a commit to Cosium/spring-hateoas that referenced this issue Apr 12, 2020
reda-alaoui added a commit to Cosium/spring-hateoas that referenced this issue Apr 12, 2020
@gregturn gregturn modified the milestones: 1.1.0.RC1, 1.2.0-M1 Apr 21, 2020
@odrotbohm
Copy link
Member

Fixed with #1269.

@odrotbohm odrotbohm modified the milestones: 1.2.0-M1, 1.1.0.RELEASE May 7, 2020
@odrotbohm odrotbohm self-assigned this May 7, 2020
@odrotbohm odrotbohm added in: mediatypes Media type related functionality type: enhancement labels May 7, 2020
odrotbohm pushed a commit that referenced this issue May 7, 2020
…Model and HAL Forms.

Original ticket: #968.
Original pull request: #1269.
odrotbohm added a commit that referenced this issue May 7, 2020
Original ticket: #968.
Original pull request: #1269.
odrotbohm pushed a commit that referenced this issue May 7, 2020
odrotbohm added a commit that referenced this issue May 7, 2020
Original pull request: #1269.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: mediatypes Media type related functionality type: enhancement
Projects
None yet
Development

No branches or pull requests

3 participants