Spring 数据剩余 - 在 _embedded 中包含嵌套资源

Spring Data Rest - Include nested resource in _embedded

我正在为购物清单开发 Spring 启动应用程序。 为此,我使用 Spring Data Rest 通过 REST API.

导出我的实体

我的架构是这样的

我有一个 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;
}

}

此购物项目包含一个导出资源的文章。

文章看起来像这样:

public class Article {

@Id
@GeneratedValue
private Long id;

@Column(unique = true)
private String name;

private Integer price;
}

当我请求 ShoppingItem 时,答案如下所示:

{
  id: 94,
  number: 1,
  bought: false,
  _links: {
    self: {
      href: "https://myDomain.tld/api/shoppingItems/94"
    },
    article: {
      href: "https://myDomain.tld/api/shoppingItems/94/article"
    }
  }
}

是否可以在请求 ShoppingItem 时将 Article 包含在 _embedded 中,以便响应看起来像这样?

{
  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'
    }
  }
}

更新 1 使用 Accept: application/x-spring-data-verbose+json

响应如下所示:

{
  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]

}

内容列表总是空的:(

更新 2:

有关我的体系结构的更多信息,请随时查看我的 Github 存储库:https://github.com/Yannic92/ShoppingList/tree/master/src/main/java/de/klem/shopping

尝试在发出请求时添加此 Accept header:

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

此外,请查看 this post,其中对此进行了详细说明。

为文章定义一个摘录投影并配置到它的存储库中 excerptProjection

任何定义了摘录投影的资源都将添加到响应的 _embedded 部分。适用于协会馆藏资源

or Spring Data REST reference documentation 阅读更多内容

只要在 _embedded 子句中使用目标类型的实例(在您的情况下为文章),就会使用摘录投影。因此 摘录是在资源本身未呈现但指向 的任何地方使用的某种预览。这通常是来自馆藏资源或协会的情况。 在 Spring Data REST 参考文档中阅读有关此主题的更多信息。

ShoppingItem 响应默认包含 Article 资源的 uri,因为您为 Article 资源定义了一个 rest 存储库 (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"
    }
  }
}

要覆盖此行为,请定义一个投影以公开文章数据 (docs):

@Projection(name = "shoppingItemDetail", types = { ShoppingItem.class }) 
interface ShoppingItemDetail { 

  // ... all other fields you want included in the response

  Article getArticle(); 

}

然后将投影作为查询参数包括在内:

https://myDomain.tld/api/shoppingItems/94?projection=shoppingItemDetail

响应现在应该包含文章数据:

{
  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"
    }
  }
}

要自动将投影包含在资源集合中,请使用摘录 (docs):

@RepositoryRestResource(excerptProjection = ShippingItemDetail.class)
interface ShippingItemRepository extends CrudRepository<ShippingItem, Long> {}