如何从 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。对于每个产品,代码
http获取商品类别url
产品类别”:{
"href":“http://localhost:8080/api/rest/products/8/productCategory”
}
http 获取类别
"productCategory":{
"href": "http://localhost:8080/api/rest/productcat/4"
},
-将描述存储在某处以便在页面上重复使用(即将其添加到 javascript 对象)
如果是这些步骤:
- 代码很多
- 对于长列表(例如 50 种产品),这是另外 100 个 http get 请求。
即使我添加了对 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。我将投影卡在存储库上而不是实体上。查看一些示例代码显示了这个问题。预测就是门票!
@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
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。对于每个产品,代码
http获取商品类别url
产品类别”:{ "href":“http://localhost:8080/api/rest/products/8/productCategory” }
http 获取类别
"productCategory":{
"href": "http://localhost:8080/api/rest/productcat/4"
},
-将描述存储在某处以便在页面上重复使用(即将其添加到 javascript 对象)
如果是这些步骤:
- 代码很多
- 对于长列表(例如 50 种产品),这是另外 100 个 http get 请求。
即使我添加了对 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。我将投影卡在存储库上而不是实体上。查看一些示例代码显示了这个问题。预测就是门票!
@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