3

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

Yannic Bürgmann
  • 6,301
  • 5
  • 43
  • 77

3 Answers3

0

Try adding this Accept header when you make the request:

Accept: application/x-spring-data-verbose+json

Also, take a look at this post where this is explained in details.

Community
  • 1
  • 1
Predrag Maric
  • 23,938
  • 5
  • 52
  • 68
  • Hi, Thank you for the fast response. I tried a request with this accept-header. The content attribute appears but its size is always 0 :( – Yannic Bürgmann Apr 16 '15 at 10:41
  • By content you mean article? – Predrag Maric Apr 16 '15 at 10:50
  • 1
    no the link you posted tells that if i use the header you mentioned this happens: (using links for the links container and content as wrapper for the collection items.). So my article should be inside the content-wrapper, shouldn't it? – Yannic Bürgmann Apr 16 '15 at 10:54
  • i updated my question so you can see the output with this header – Yannic Bürgmann Apr 16 '15 at 11:03
  • Sorry, I wrote `compact` instead of `verbose` in header content. I've edited my answer. Can you try with `application/x-spring-data-verbose+json`? – Predrag Maric Apr 16 '15 at 11:11
  • 2
    I forgot to accept your answer.. the header didn't and still doesn't work for me, but the hint to projections of oliver gierke in the post you linked helped me. – Yannic Bürgmann Sep 24 '15 at 15:00
0

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.

Community
  • 1
  • 1
pdorgambide
  • 1,787
  • 19
  • 33
0

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> {}
Leroy Dunn
  • 361
  • 4
  • 7