Closed
Description
@drdamour I'm experimenting on a fluent API to build RepresentationModel
objects. What do you think of something like this for building an embedded structure like you depicted up above?
@RestController
static class ProductController {
LinkRelation favoriteProducts = LinkRelation.of("favorite products");
LinkRelation purchasedProducts = LinkRelation.of("purchased products");
@GetMapping("/products")
public RepresentationModel<?> all() {
EmbeddedModelBuilder builder = ModelBuilder //
.embed() //
.rootLink(linkTo(methodOn(ProductController.class).all()).withSelfRel());
PRODUCTS.keySet().stream() //
.map(id -> new EntityModel<>(PRODUCTS.get(id), new Link("http://localhost/products/{id}").expand(id))) //
.forEach(productEntityModel -> {
if (productEntityModel.getContent().isFavorite()) {
builder //
.embed(favoriteProducts) //
.entityModel(productEntityModel) //
.rootLink(productEntityModel.getRequiredLink(SELF).withRel(favoriteProducts));
}
if (productEntityModel.getContent().isPurchased()) {
builder //
.embed(purchasedProducts) //
.entityModel(productEntityModel) //
.rootLink(productEntityModel.getRequiredLink(SELF).withRel(purchasedProducts));
}
});
return builder.build();
}
}
It yields:
{
"_embedded" : {
"favorite products" : [ {
"someProductProperty" : "someValue",
"_links" : {
"self" : {
"href" : "http://localhost/products/777"
}
}
}, {
"someProductProperty" : "someValue",
"_links" : {
"self" : {
"href" : "http://localhost/products/998"
}
}
} ],
"purchased products" : [ {
"someProductProperty" : "someValue",
"_links" : {
"self" : {
"href" : "http://localhost/products/111"
}
}
}, {
"someProductProperty" : "someValue",
"_links" : {
"self" : {
"href" : "http://localhost/products/222"
}
}
}, {
"someProductProperty" : "someValue",
"_links" : {
"self" : {
"href" : "http://localhost/products/333"
}
}
}, {
"someProductProperty" : "someValue",
"_links" : {
"self" : {
"href" : "http://localhost/products/444"
}
}
}, {
"someProductProperty" : "someValue",
"_links" : {
"self" : {
"href" : "http://localhost/products/555"
}
}
}, {
"someProductProperty" : "someValue",
"_links" : {
"self" : {
"href" : "http://localhost/products/666"
}
}
}, {
"someProductProperty" : "someValue",
"_links" : {
"self" : {
"href" : "http://localhost/products/998"
}
}
} ]
},
"_links" : {
"self" : {
"href" : "http://localhost/products"
},
"purchased products" : [ {
"href" : "http://localhost/products/111"
}, {
"href" : "http://localhost/products/222"
}, {
"href" : "http://localhost/products/333"
}, {
"href" : "http://localhost/products/444"
}, {
"href" : "http://localhost/products/555"
}, {
"href" : "http://localhost/products/666"
}, {
"href" : "http://localhost/products/998"
} ],
"favorite products" : [ {
"href" : "http://localhost/products/777"
}, {
"href" : "http://localhost/products/998"
} ]
}
}
A plain old collection where the embedded link relation is a based on the domain type:
@GetMapping("/authors")
RepresentationModel<?> collection() {
return ModelBuilder //
.collection() //
.entity(new Author("Greg L. Turnquist", null, null)) //
.link(linkTo(methodOn(EmbeddedController.class).authorDetails(1)).withSelfRel())
.link(linkTo(methodOn(EmbeddedController.class).collection()).withRel("authors")) //
.entity(new Author("Craig Walls", null, null)) //
.link(linkTo(methodOn(EmbeddedController.class).authorDetails(2)).withSelfRel())
.link(linkTo(methodOn(EmbeddedController.class).collection()).withRel("authors")) //
.entity(new Author("Oliver Drotbhom", null, null)) //
.link(linkTo(methodOn(EmbeddedController.class).authorDetails(2)).withSelfRel())
.link(linkTo(methodOn(EmbeddedController.class).collection()).withRel("authors")) //
.rootLink(linkTo(methodOn(EmbeddedController.class).collection()).withSelfRel()) //
.build();
}
produces
{
"_embedded" : {
"authors" : [ {
"name" : "Greg L. Turnquist",
"_links" : {
"self" : {
"href" : "http://localhost/author/1"
},
"authors" : {
"href" : "http://localhost/authors"
}
}
}, {
"name" : "Craig Walls",
"_links" : {
"self" : {
"href" : "http://localhost/author/2"
},
"authors" : {
"href" : "http://localhost/authors"
}
}
}, {
"name" : "Oliver Drotbhom",
"_links" : {
"self" : {
"href" : "http://localhost/author/2"
},
"authors" : {
"href" : "http://localhost/authors"
}
}
} ]
},
"_links" : {
"self" : {
"href" : "http://localhost/authors"
}
}
}
And a single item representation:
@GetMapping("/other-author")
RepresentationModel<?> singleItem() {
return ModelBuilder //
.entity(new Author("Alan Watts", "January 6, 1915", "November 16, 1973")) //
.link(new Link("/people/alan-watts")) //
.build();
}
produces
{
"name" : "Alan Watts",
"born" : "January 6, 1915",
"died" : "November 16, 1973",
"_links" : {
"self" : {
"href" : "/people/alan-watts"
}
}
}
Related issue: #175