2017-09-27 104 views
1

我需要跟踪实体的观看次数。例如我有一个Product实体,具有下列API端点:弹簧安置控制器轨迹实体查看次数

GET /products/{productID} 

在情况下,我想跟踪的查看次数一个特定的Product我应该添加额外的逻辑,当我呼叫这个/products/{productID}端点时将增加查看计数?或者我应该为此目的引入一个单独的端点?

修订

也许我不是清楚我的问题,但我的问题是用于更新与REST API柜台不是多层架构有关的最佳实践。我想问以下 - 我应该更新计数器提到GET请求,或者我应该引入另一个API ..让我们说POST /products/{productID}/viewings,然后在GET之后调用它以更新计数器?

+0

控制器处理Web的东西,服务实现业务逻辑,数据库(dao)访问数据库。 – DwB

回答

1

是视图指望产品实体财产还是

如果查看计数是属性,则考虑单独的PUTPATCH请求更新它。

A GETsafe method并且不应该更新被请求的资源。如果客户端预取和/或缓存该安全请求的结果,那么您的浏览次数就会不正确。

问自己的另一个问题是查看计数是否与该资源的GET请求同义。换句话说,除了用户视图以外,您的应用可能会对资源执行GET。如果是这样,那将是另一个在单独的非安全请求中增加查看次数的原因。

如果查看计数确实是元数据,并且GET确实等同于用户视图,那么我会继续增加GET上的计数器。单独的请求会产生成本,并且每次安全请求都可能在服务器上发生其他无害的副作用(例如记录)。

0

这对于AOP(面向方面​​编程)来说似乎是一个很好的场景,因为这将允许您将此统计逻辑从业务逻辑中分离出来。

看看Spring doc了解更多关于AOP的信息以及如何通过Spring实现这一点。

然后,您可以在您的控制器上定义一个切入点,并拥有一个用于计数(并可能存储)数据的服务。

0

至于如何开始使用SpringMVC中的RestController,以下是一个快速入门示例(使用products/{id}和JSON/XML req方法,JSON是直/ id并且XML是/id.xml)。

@RestController 
@RequestMapping("products") 
public class ProductsController { 

    @RequestMapping(value = "/{id}", method = RequestMethod.GET, produces = "application/json") 
    public Product getProductInJSON(@PathVariable String id) { 

     //...Service/DAO fetch based on "id" 
     Product p = service.getProduct(id); 
     return p; 
    } 

    @RequestMapping(value = "/{id}.xml", method = RequestMethod.GET, produces = "application/xml")  
    public Product getProductInXML(@PathVariable String id) { 

     //...Service/DAO fetch based on "id" 
     Product p = service.getProduct(id); 
     return p; 

    } 
} 

关于点击数,是的,我只想补充额外的逻辑控制器 - 可能比拦截清洁/简单。

0

不要将计数放在控制器或AOP拦截器中;这两个问题都是可怕的解决方案。

你应该有一个数据源来提供关于产品(可能是数据库)的信息。 您应该使用JDBC包装来访问数据库(也许是使用Hibernate或MyBatis编写的DAO)。 您还应该拥有一个由控制器调用的用于检索给定数据源的服务(如基因b的答案中所示)。

将访问计数放入数据库代码(DAO)或服务中。

将计数存储在数据库中(也许创建一个AccessedProducts表)。

+0

感谢您的回答。也许我不清楚我的问题,但我的问题是有关使用REST API更新计数器的最佳做法,而不是关于多层体系结构。我想问以下问题 - 是否应该通过提到的GET请求来更新计数器,或者我应该引入另一个API ..让我们说'POST/products/{productID}/viewings',然后在GET之后调用它。为了更新柜台? – alexanoid

1

理想情况下,它应该是后续调用,因为GET服务用于检索值。既然你有更新的数,您可以使用相同的服务在POST几乎相同的逻辑下面给出:

 @RequestMapping(value = "/product/{id}", method = { RequestMethod.GET, RequestMethod.POST }) 
     public Product getProduct(@PathVariable String id){ 
      //get and update product 
return product; 
    }