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 を使用すると、必要なものを簡単に実現する方法が 2 つあります。

  1. Invoice および Item エンティティを作成し、Invoice エンティティのリポジトリのみを作成します。それはアイテムをインライン化します。欠点としては、項目自体を照会することができません。これはおそらくあなたが望むものではありません。
  2. 両方のエンティティを作成し、両方のリポジトリも作成します。Invoice リポジトリで抜粋を作成します。これはクエリ可能で、アイテムが埋め込まれており、それぞれのリンク コレクションが含まれています。ただし、欠点もあります。埋め込まれたアイテムにはリンクがありません。Projection 内で Resource を使用して、そこにリンクを含めることができるはずです。

Order with Items を使用したサンプル コードを参照してください。

@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 に答える