数据处理和转换应该在哪里发生?

时间:2017-12-12 14:19:50

标签: design-patterns transformation server-side client-side api-design

我使用Angular 4作为我的前端框架,基本上只是asp net core作为客户端从中获取数据并偶尔发布数据的API。

我正在制作一个仪表板来显示一些统计数据。我在数据库中拥有的数据不能直接用于此仪表板,因为它需要进行转换和进一步处理。我没有将模型实体返回到API,而是View Model,它与模型实体基本相同,删除了一些ID等。

我现在所拥有的是我的Angular DashboardComponent正在使用DataService来构建HTTP GET请求,该请求指向我现有的API端点GetOrders。这将从数据库获取所有订单并将其返回到DataService,最后返回DashboardComponent,然后需要提取数据并进行大量处理和转换,以便准备好将数据提供给可以生成Google Charts和有意义的图表。然后,用户可以选择在仪表板上查看另一个图表,然后仅仅拥有Orders,但还必须从数据库中检索另一个实体,因此使用不同的终点重复上述API调用。

我的问题归结为:

  • 最好是在服务器端进行所有处理和转换,并将数据返回到几乎准备好呈现的客户端,或者离开客户端是否正常有这项任务吗?
  • 如果是服务器端处理和转换,我是否应该以这样的方式构建它,即我的API端点对应于我想在仪表板中显示的数据类型?那么,选择例如“英国最近3个月的订单”会向API端点发送请求,该请求专门采用国家和期间等参数吗?
  • 也许数据应该已经是我可以通过某种数据仓库用于仪表板的形状了?这是这样的吗?

总的来说,我正在寻找一些关于这个或者只是最佳实践的设计模式,但实际上并没有找到一些东西。

2 个答案:

答案 0 :(得分:1)

  • 最好是在服务器端进行所有处理和转换,并将数据返回到几乎准备好呈现的客户端,还是让客户端完成此任务?

    首选服务器端处理和转换。这样,如果您的对象模型/实体发生更改,则可以使客户端不知道某些内容发生了更改。有更多的原因,但应该是一个更大的原因。

  • 在服务器端处理和转换的情况下,我是否应该以这样的方式构建它:我的API端点对应于我想在仪表板中显示的数据类型?因此,选择例如"英国最近3个月的订单"会向API端点发送请求,该端点专门接受国家和期间等参数吗?

    您必须根据您要处理的用例来决定这一点,并将其与性能考虑因素和可重用性进行平衡(例如,您是否应该选择一种能够返回大对象的方法)具有大量数据或多个方法,以最少的数据返回小对象)。这里没有明确规定。

  • 也许数据应该已经是我可以通过某种数据仓库用于仪表板的形状了?这是这样的方式吗?

    这里也没有明确规定。数据和预算的规模将对此进行定义。你可以使用.net核心项目中的.Net代码来塑造你的数据,或者你可以拥有一个大规模的数据仓库来扩展数PB的数据...这些都是完全有效和荒谬的答案,具体取决于你的用例。

一般"肠道检查"可以帮助你确定放在哪里的东西...

  • 您希望您的视图与数据相关的计算接近零,视图中的所有逻辑都应该是特定于视图的

    e.g。

    • 可以查看:如果某些内容为true / false隐藏此/那并禁用此/

    • 属于视图之外: order_tax = tax_rate_for_state * total;

  • 如果其他人想要编写一个视图来显示您所做的统计繁重,那么您当前的api(asp.net控制器方法)是否会隔离写入视图的人知道任何其他内容?是的,这是你应该努力的。例如如果iPhone应用程序调用您的api GetOrderTotal(orderNumber),则该iPhone应用程序不应该知道您的折扣结构。

  • 当你让控制器方法返回一个整形结果时,是在一个地方塑造数据的代码吗?在一个区域完成一些工作,在一个区域完成一些工作只会使调试变得更加困难。您不希望发生的一个例子是

    [HttpGet]       
    public double GetOrderTotal(string orderNumber)
    {
        // lets pretend here that we have a stored proc that returns an orderTotal
        var orderTotal = _orderService.GetOrderTotalUsingStoredProc(orderNumber);
    
        // this if else if block should be pushed at to the _orderService method 
        // or the OrderTotal stored procedure, otherwise any other code that relies
        // on _orderService.GetOrderTotalUsingStoredProc might not know that discounts
        // are applied to certain threshold amounts
    
        if (orderTotal > 1000)
        {
            orderTotal = orderTotal * 0.9
        } 
        else if (orderTotal > 10000)
        {
            orderTotal = orderTotal * 0.85
        }
    
        return orderTotal;
    }
    

答案 1 :(得分:0)

这不是应该使用什么设计模式的问题,而是应遵循的最佳实践。在我有限的经验中,应尽可能避免客户端的数据处理和转换。 要回答第二个问题,是否应在客户端过滤数据,或者将过滤条件传递给后端以获取相同的数据。这取决于几个因素:

  • 数据大小
  • 您将应用于数据的过滤器种类

如果您的数据很大,您可能希望避免在后端提取整个数据并过滤数据,否则您可能希望在客户端本身过滤数据。