Laravel JSON API: 如何从数据库中创建自定义的虚拟资源(用于聚合值)?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Laravel JSON API: 如何从数据库中创建自定义的虚拟资源(用于聚合值)?相关的知识,希望对你有一定的参考价值。

自从几天前我想知道如何添加一个 "虚拟 "资源到我的Laravel JSON API中 ("cloudcreativity/laravel-json-api": "~2.0"). 来解释一下。

假设我在数据库表中有一个定时器记录和一个Eloquent模型,JSON API包使用它自动将其转换为资源,显示在 /api/v1/timerecords. 通过添加一个适配器、一个Schema和一些小的配置,这在开箱即用的情况下效果非常好。例如定时器记录。

id | customer_id | user_id | ts_start | ts_end | hours | amount_xy | ...
1  | 123         | 5       | 2020-0...| 2020...| 4.5   | 95.2      | ...
2  | 987         | 5       | 2020-0...| 2020...| 2.75  | 32.8      | ...

但现在我想有一个API端点: /api/v1/timeaggregates 的计算值,如 COUNT(id) AS num_records, SUM(hours) AS sum_hours, AVG(amount_xy) AS avg_xy,其中,这些记录可以通过各种参数(或过滤器留在API术语?)进行汇总,如。

  • "CUSTOMER=123的DATE-ROM和DATE-TO之间的聚合值"
  • "CUSTOMER=123的总值"
  • "CUSTOMER=123和USER=5的合计值"

当然,这个资源必须是只读的(GET),因为它是 "虚拟 "的。但我甚至无法接近任何工作。而且搜索整个网络也没有任何结果,这让我更加奇怪,因为我发现这样的功能对于一个API来说是一个很常见的任务,不是吗?到目前为止,我已经尝试了什么。

  • 尝试创建一个... EloquentCollection. 问题是,我无法在某个地方使用这个Collection,因为只有一个通用的JsonApiController。
  • 尝试使用一个虚拟模型(jenssegerslaravel-model-----。),但JSON API希望收到Eloquent模型的
  • 从其他框架中我知道Repository模式,我会在那里实现这样的聚合函数,但Laravel似乎没有实现这种模式,即使我自己做,又该在哪里调用Repository函数?
  • ......无数次的尝试

也许我在这里错过了一些重要的东西,或者问题可能是使用CloudCreativity包,它不支持这样的事情(再次,这将使我怀疑,因为该包似乎非常专业,有很好的文档)。

我appreachiate如果你们有人能给我一个提示。謝謝你們

答案

我创造了一个丑陋的工作方法。如果有更简洁的解决方案,请随时指导我^^。

首先,我创建了一个 "虚拟 "模型,这并不是真正的虚拟,因为我使用了一个现有的 "定时器记录 "表。

class Timeaggregate extends Model {
    protected $table = 'timerecords';
}

在资源适配器中,我覆盖了 "时间记录 "表 queryAll() 方法来计算汇总值。

    protected function queryAll($query, EncodingParametersInterface $parameters) {
        $this->with($query, $parameters);
        $this->applyFilters($query, collect($parameters->getFilteringParameters()));

        $query->selectRaw('COUNT(id) as count_records')
            ->selectRaw('SUM(hours) AS sum_hours');

        return $query->first();
    }

比起资源模式的getAttributes()方法,我可以简单地将计算出的字段添加到响应中,例如: $resource->sum_hours.

另一个解决方案可能是创建一个非eloquent资源,并手动执行数据库查询以填充所需的属性。但是我还没有测试过,因为我发现我的需求和一个真实存在的资源关系非常密切,所以在我看来,它应该还是一个Eloquent资源。

以上是关于Laravel JSON API: 如何从数据库中创建自定义的虚拟资源(用于聚合值)?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Guzzle 和 Laravel 从 JSON 响应中提取单个数组值

将 JSON 数据从 API 转换为数组并在 Laravel 和 Guzzle HTTP Client 中分别显示?

如何将 JSON 对象从 React Native 发送到 Laravel 服务器?

Vue + Laravel:如果元组数据之一中的表单数组中的数据,如何从api挂载数据

使用 Laravel 从 API 获取 JSON 响应

Laravel API 身份验证(Passport),从 post application/json 获取用户 ID