如何循环并从HATEOAS _link属性中检索值(例如,检索描述)? [英] How to loop and retrieve value from HATEOAS _link attribute (e.g. retrieve a description)?

查看:100
本文介绍了如何循环并从HATEOAS _link属性中检索值(例如,检索描述)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

tl; dr

我的代码从Restful GET获取了一个javascript/json对象数组.如何编写代码以循环并从HATEOAS"_link"属性中检索描述(或任何值)以进行显示?

上下文

我继承了一个基于Spring的小项目-它跟踪服务器,软件安装等,以供我们团队内部使用.它使用Angular前端和Spring/java/mysql后端实现宁静的后端.

I've inherited a small Spring-based project --it tracks servers, software installations, etc for our team's internal use. It uses Angular front end and Spring/java/mysql back end for a restful back end.

我正在将手动编码的SQL转换为JPA和"Spring Starter Data Rest".

I'm in the process of converting the hand-coded SQL to JPA and 'spring starter data rest'

当前的API可以

当前的手工编码SQL连接表以提供显示友好的结果".

The current handcoded SQL joins tables to give "display friendly results".

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

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

检索产品" sql将产品和类别连接在一起,以给出显示友好名称". Rest API检索带有此类别名称"的产品对象".

The 'retrieve products' sql joins product and category to give a 'display friendly name'. The Rest API retrieves an 'product object' with this 'category name' tacked on.

Spring Data Rest域对象

产品

@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存储库.现在,获取产品"静态API将返回以下列表:

I've removed the joins, and added Spring repositories for Product and Category. The 'get products' restful API now returns a list of these:

{
      "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"链接的类别名称?

How do I display the category name for the "productCategory" link?

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

最初,我认为我可以检索类别,然后将类别url"映射到描述".但是网址不同:

I initially thought I could retrieve the categories, then build a map of 'category url' to 'description.' However the url's differ:

产品类别"网址看起来像这样: http://localhost:8080/api/rest/productcat/1

The 'product category' url looks liks this: http://localhost:8080/api/rest/productcat/1

该产品具有以下特点: 产品分类" : { "href":" http://localhost:8080/api/rest/products/8/productCategory " }

Whereas the Product has this: "productCategory" : { "href" : "http://localhost:8080/api/rest/products/8/productCategory" }

问题澄清

因此,如果javascript控制器http获得了该产品:

so if the javascript controller http gets the products:

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

那又怎样?这些步骤了吗?

So then what? Are these the steps?

javascript控制器循环遍历每个data._embedded.products.每个产品的代码

The javascript controller loops through each data._embedded.products. for each product, the code

  • http获取产品类别网址

  • http gets the product category url

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

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

http获取类别

"productCategory":{

"productCategory": {

"href": "http://localhost:8080/api/rest/productcat/4"

},

-将描述存储在页面上的某个地方以供重复使用(即,将其添加到javascript对象中)

-stores the description somewhere for reuse on the page (i.e. adding it to the javascript object )

如果这些步骤是:

  • 很多代码
  • 对于较长的列表(例如50种产品),这是另外100个http get请求.

即使我添加了一个获取/缓存所有产品类别的调用,那仍然是额外的50个http获取

Even if I add a call to get/cache all product categories, that's still an extra 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();
       }
    }

但是,此网址未返回类别名称:

However this url does not return the category name:

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

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

Additionally, I set debugging on for these

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

日志/控制台未提及任何投影.

Log/console do not mention any projections.

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

Attempt #02: Fixed Projections File under D for D'oh. I stuck projection on the repository not on the entity. Reviewing some sample code showed the issue. Projections are the ticket!

推荐答案

}

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

Just include projection name in your request ex: /products?projection=dummyNameForProjection

这篇关于如何循环并从HATEOAS _link属性中检索值(例如,检索描述)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆