数据处理和转换应该在哪里进行?

DSF*_*DSF 2 design-patterns api-design transformation server-side client-side

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

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

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

我的问题归结为:

  • 最好是在服务器端完成所有处理和转换并将几乎准备好呈现的数据返回给客户端,还是可以让客户端来完成此任务?
  • 在服务器端处理和转换的情况下,我是否应该以这样的方式构建它:我的 API 端点与我想要在仪表板中显示的数据类型相对应?那么,例如选择“英国过去 3 个月的订单”会向专门采用国家/地区和时期等参数的 API 端点发送请求吗?
  • 也许数据应该已经是我可以通过某种数据仓库用于仪表板的形状了?这是要走的路吗?

一般来说,我正在寻找一些关于此的设计模式或只是最佳实践,但还没有真正找到一些东西。

小智 5

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

    更喜欢服务器端处理和转换。这样,如果您的对象模型/实体发生变化,客户端就可以不知道某些内容发生了变化。原因还有很多,但其中一个应该是最大的原因之一。

  • 在服务器端处理和转换的情况下,我是否应该以这样的方式构建它:我的 API 端点与我想要在仪表板中显示的数据类型相对应?那么,例如选择“英国过去 3 个月的订单”会向专门采用国家/地区和时期等参数的 API 端点发送请求吗?

    您必须根据要处理的用例来决定这一点,并在性能考虑和可重用性之间进行平衡(例如,您应该选择一种将返回包含大量数据的大对象的方法,还是选择多种方法)返回具有最少数据的小对象)。这里没有明确的规则。

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

    这里也没有明确的规则。数据规模和预算将定义这一点。您可以在 .net core 项目中使用 .Net 代码来塑造数据,或者您可以拥有一个可扩展 PB 级数据的大型数据仓库……根据您的用例,这两种答案都是完全有效且荒谬的答案。

一般的“直觉检查”可以帮助您确定将什么放在哪里......

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

    例如

    • 可以查看:如果某件事是真/假,则隐藏这个/那个并禁用这个/那个

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

  • 如果其他人想要编写一个视图来显示您所做的统计繁重工作,您当前的 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;
    }
    
    Run Code Online (Sandbox Code Playgroud)