1

我正在寻找如何使用 Spring HATEOAS API 对 HAL 中的嵌套 _embedded 进行编程的示例。最佳做法是什么?

这是我想要实现的示例:

{
    "_links": {
        "self": { "href": "/invoices" }
    },
    "_embedded": {
        "invoices": [
            {
                "_links": {
                    "self": { "href": "/invoice/1" }
                },
                "_embedded": {
                    "items": [
                        { "_links": { "self": { "href": "/product/1" }}, "id": 1, "name": "Super cheap Macbook Pro", "price": 2.99 }
                    ]
                },
                "id": 1,
                "total": 2.99,
                "no_items": 1
            },
            {
                "_links": {
                    "self": { "href": "/invoice/2" }
                },
                "_embedded": {
                    "items": [
                        { "_links": { "self": { "href": "/product/2" }}, "id": 2, "name": "Raspberry Pi", "price": 34.87 },
                        { "_links": { "self": { "href": "/product/3" }}, "id": 3, "name": "Random product", "price": 30 },
                        { "_links": { "self": { "href": "/product/4" }}, "id": 4, "name": "More randomness", "price": 30 }
                    ]
                },
                "id": 2,
                "total": 94.87,
                "no_items": 3
            }
        ]
    }
}
4

1 回答 1

0

使用 Spring Data REST 和 Spring HATEOAS,我看到了两种轻松实现您想要的方式的方法。

  1. 创建一个 Invoice 和 Item 实体并仅为 Invoice 实体创建一个存储库。这将内联项目。不利的一面是,您无法自行查询项目,这可能不是您想要的。
  2. 创建两个实体并为它们创建存储库。现在在 Invoice 存储库上创建一个Excerpt,可以对其进行查询并嵌入项目并包含相应的链接集合。但也有一个缺点:嵌入的项目上不会有链接。我认为您应该能够通过使用 Projection 中的 Resource 在其中包含链接。

查看一些使用带有项目的订单的示例代码:

@Data
@Entity
public class Item {
  @Id
  @GeneratedValue
  private Long id;
  private String name;
}

@Data
@Entity
@Table(name = "customer_order")
public class Order {
  @Id
  @GeneratedValue
  private Long id;
  private String name;
  @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
  private Collection<Item> items;
}

public interface ItemRepository extends CrudRepository<Item, Long> {
}

@RepositoryRestResource(excerptProjection = InlineItems.class)
public interface OrderRepository extends CrudRepository<Order, Long> {
}

@Projection(name = "inlineItems", types = Order.class)
public interface InlineItems {
  String getName();

  Collection<Item> getItems();
}

您可以像这样查询订单GET http://localhost:8080/orders/1?projection=inlineItems,这将导致以下结果:

{
  "name": "My Order",
  "items": [
    {
      "name": "Banana"
    },
    {
      "name": "Apple"
    }
  ],
  "_links": {
    "self": {
      "href": "http://localhost:8090/api/orders/1"
    },
    "order": {
      "href": "http://localhost:8090/api/orders/1{?projection}",
      "templated": true
    },
    "items": {
      "href": "http://localhost:8090/api/orders/1/items"
    }
  }
}
于 2016-03-02T09:48:26.540 回答