'Spring Data Rest - Include nested resource in _embedded
I'm developing a Spring Boot Application for a shopping list. For this I use Spring Data Rest to export my entities through a REST API.
My Architecture looks like this
I have a ShoppingItem:
public class ShoppingItem {
@Id
@GeneratedValue
private Long id;
@ManyToOne
@JoinColumn(name = "articleId", nullable = false)
private Article article;
private Integer number;
private boolean bought;
public ShoppingItem(){
this.article = null;
this.number = 0;
this.bought = false;
}
}
This shopping item contains an Article which is an exported Resource.
The Article looks like this:
public class Article {
@Id
@GeneratedValue
private Long id;
@Column(unique = true)
private String name;
private Integer price;
}
When i request a ShoppingItem the answer looks like this:
{
id: 94,
number: 1,
bought: false,
_links: {
self: {
href: "https://myDomain.tld/api/shoppingItems/94"
},
article: {
href: "https://myDomain.tld/api/shoppingItems/94/article"
}
}
}
Is it possible to include the Article in _embedded when requesting the ShoppingItem so the response looks like this?
{
id: 94,
number: 1,
bought: false,
_links: {
self: {
href: "https://myDomain.tld/api/shoppingItems/94"
},
article: {
href: "https://myDomain.tld/api/shoppingItems/94/article"
}
},
_embedded: {
article: {
id: '999',
name: 'someThing',
price: '1.99'
}
}
}
update 1
When using Accept: application/x-spring-data-verbose+json
The response looks like this:
{
id: 94
number: 1
bought: false
links: [2]
0: {
rel: "self"
href: "https://wg.yannic-klem.de/api/shoppingItems/94"
}-
1: {
rel: "article"
href: "https://wg.yannic-klem.de/api/shoppingItems/94/article"
}-
-
content: [0]
}
The content-List is always empty :(
update 2:
For more information about my architecture feel free to have a look at my Github repo : https://github.com/Yannic92/ShoppingList/tree/master/src/main/java/de/klem/shopping
Solution 1:[1]
Define an excerpt projection for Article and configure into its repository with
excerptProjection
Any resource that has defined an excerpt projection will be added to _embedded part fo the response. This applies to collecion resources of associations.
Read more at https://stackoverflow.com/a/30297320/1203628 or Spring Data REST reference documentation
An excerpt projection is used whenever an instance of the target type (Article in your case) is used within in an _embedded clause. Thus the excerpt is some kind of preview used everywhere the resource itself is not rendered but pointed to. This is usually the case from collection resources or for associations. Read more on this topic in the Spring Data REST reference documentation.
Solution 2:[2]
The ShoppingItem response includes a uri to your Article resource by default since you defined a rest repository for your Article resource (docs)
{
id: 94,
number: 1,
bought: false,
_links: {
self: {
href: "https://myDomain.tld/api/shoppingItems/94"
},
article: {
href: "https://myDomain.tld/api/shoppingItems/94/article"
}
}
}
To override this behaviour, define a projection to expose the article data (docs):
@Projection(name = "shoppingItemDetail", types = { ShoppingItem.class })
interface ShoppingItemDetail {
// ... all other fields you want included in the response
Article getArticle();
}
Then include the projection as a query parameter:
https://myDomain.tld/api/shoppingItems/94?projection=shoppingItemDetail
The response should now include the article data:
{
id: 94,
number: 1,
bought: false,
article: {
id: '999',
name: 'someThing',
price: '1.99'
}
_links: {
self: {
href: "https://myDomain.tld/api/shoppingItems/94"
},
article: {
href: "https://myDomain.tld/api/shoppingItems/94/article"
}
}
}
To automatically include the projection on a collection of resources, use an excerpt (docs):
@RepositoryRestResource(excerptProjection = ShippingItemDetail.class)
interface ShippingItemRepository extends CrudRepository<ShippingItem, Long> {}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Community |
| Solution 2 | Leroy Dunn |
