如何从 HATEOAS _link 属性循环和检索值(例如检索描述)?

How to loop and retrieve value from HATEOAS _link attribute (e.g. retrieve a description)?

tl;dr

我的代码从 Restful GET 获取一个 javascript/json 对象数组。如何编写代码来循环和检索 HATEOAS“_link”属性中的描述(或任何值)以便显示?

上下文

我继承了一个基于 Spring 的小项目 -- 它跟踪服务器、软件安装等供我们团队内部使用。它使用 Angular 前端和 Spring/java/mysql 后端作为 restful 后端。

我正在将手动编码的 SQL 转换为 JPA 和 'spring starter data rest'

当前API

当前手写SQL 连接表给"display friendly results".

Product
---------
Product ID
Product Name
Category ID

Category
---------
Category ID
Category Name

'retrieve products' sql 加入产品和类别给出 'display friendly name'。其余 API 检索一个 'product object' 加上这个 'category name'。

Spring 数据休息域对象

产品

@Entity
@Table(name="products")
public class Products
{

    private static final long serialVersionUID = 5697367593400296932L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)

    public long id;

    public String product_name;

    @ManyToOne(optional = false,cascade= CascadeType.MERGE)
    @JoinColumn(name = "category_id")
    private ProductCategory productCategory;

    public Products(){}

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public Products(String product_name) {
        this.product_name = product_name;
    }

    public String getProduct_name() {
        return product_name;
    }

    public void setProduct_name(String product_name) {
        this.product_name = product_name;
    }

    public ProductCategory getProductCategory()
    {
        return productCategory;
    }

    public void setProductCategory(ProductCategory pProductCategory)
    {
        productCategory = pProductCategory;
    }
}

产品类别

@Entity
@Table(name="productcat")

public class ProductCategory implements Serializable{

        private static final long serialVersionUID = 890485159724195243L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public long id;
    public String category;

    @OneToMany(mappedBy = "productCategory", cascade = CascadeType.ALL)
    @JsonBackReference
    Set<Products> products;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getCategory() {
        return category;
    }

    public void setCategory(String category) {
        this.category = category;
    }

    public Set<Products> getProducts() {
        return products;
    }

}

问题

我删除了连接,并为产品和类别添加了 Spring 存储库。 'get products' restful API 现在 return 是这些列表:

{
      "product_name" : "ForceFive 1.0",
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/api/rest/products/8"
        },
        "products" : {
          "href" : "http://localhost:8080/api/rest/products/8"
        },
        "productCategory" : {
          "href" : "http://localhost:8080/api/rest/products/8/productCategory"
        }
      }

问题

如何显示 "productCategory" link 的类别名称?

"productCategory" : {
  "href" : "http://localhost:8080/api/rest/products/8/productCategory"
}

我最初认为我可以检索类别,然后构建一个 'category url' 到 'description.' 的映射,但是 url 的不同:

'product category' url 看起来像这样: http://localhost:8080/api/rest/productcat/1

而产品有这个: "productCategory":{ "href":“http://localhost:8080/api/rest/products/8/productCategory” }

问题说明

所以如果 javascript 控制器 http 获取产品:

requests.get(productsUrl, $scope).success(function(data, status){
    $scope.models = data._embedded.products;  
});

然后呢?这些是步骤吗?

javascript 控制器循环遍历每个 data._embedded.products。对于每个产品,代码

-将描述存储在某处以便在页面上重复使用(即将其添加到 javascript 对象)

如果是这些步骤:

即使我添加了对 get/cache 所有产品类别的调用,这仍然是额外的 50 个 http gets

奖金:

尝试 #01:添加了投影

我添加了这个投影:

  public interface ProductRepository extends PagingAndSortingRepository<Products, Long>
    {

       @Projection(name = "dummyNameForProjection", types = { Products.class })
       interface VirtualProjection
       {

          String getProduct_name() ;
          //Get Product Category
          @Value("#{target.productCategory.category}")
          String getCategoryName();
       }
    }

但是这个url没有return类别名称:

http://localhost:8080/api/rest/products/4?projection=dummyNameForProjection

返回json

{
    "product_name": "Force Five",
    "_links": {
        "self": {
            "href": "http://localhost:8080/api/rest/products/4"
        },
        "products": {
            "href": "http://localhost:8080/api/rest/products/4"
        },
        "productCategory": {
            "href": "http://localhost:8080/api/rest/products/4/productCategory"
        }
    }
}

此外,我为这些设置了调试

 logging.level.org.springframework.data=DEBUG
 logging.level.org.springframework.data.rest=DEBUG
 logging.level.org.hibernate=DEBUG

Log/console不提任何推算。

尝试 #02:固定投影 在 D 下归档 D'oh。我将投影卡在存储库上而不是实体上。查看一些示例代码显示了这个问题。预测就是门票!

Spring Projection

@Projection(name = "dummyNameForProjection", types = { Product.class })
public interface VirtualProjection {

// this will get the attribute name from the product entity
String getProductName();

//this will get the name of the category entity related to the product
@Value("#{target.category.name}") 
String getCategoryName();

}

只需在您的请求中包含投影名称,例如:/products?projection=dummyNameForProjection