laravel - Laravel JSON API:如何从数据库创建自定义虚拟资源(用于聚合值)?
问题描述
从那以后,我试图弄清楚如何将“虚拟”资源添加到我的 Laravel JSON API ( "cloudcreativity/laravel-json-api": "~2.0"
)。解释:
假设我在数据库表和 Eloquent 模型中有时间记录,JSON API 包使用该模型将其自动转换为资源,显示在/api/v1/timerecords
. 开箱即用,只需添加一个适配器、一个模式和一些微小的配置!时间记录示例:
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/v1/timeaggregates
带有计算值的 API 端点,例如COUNT(id) AS num_records, SUM(hours) AS sum_hours, AVG(amount_xy) AS avg_xy
,这些记录可以通过各种参数聚合(或过滤器以保持 API 术语?!),例如:
- “CUSTOMER=123 的 DATE-FROM 和 DATE-TO 之间的聚合值”
- “CUSTOMER=123 的聚合值”
- “CUSTOMER=123 和 USER=5 的聚合值”
当然,这个资源必须是只读的(GET),因为它是“虚拟的”。但我什至无法接近任何工作。搜索整个网络也一无所获,这让我更加好奇,因为我发现这样的功能对于 API 来说是一项非常常见的任务,不是吗?!到目前为止我已经尝试过:
- 试图创建一个
Eloquent\Collection
. 问题是我无法在某个地方使用这个集合,因为只有一个通用的 JsonApiController。 - 尝试使用虚拟模型 ( jenssegers/laravel-model ),但 JSON API 期望接收 Eloquent 模型
- 从其他框架中,我知道我将在其中实现此类聚合函数的存储库模式,但 Laravel 似乎没有实现此模式,即使我自己做,又在哪里调用存储库函数?
- ...无数其他尝试
也许我在这里遗漏了一些巨大的东西,或者问题可能是使用了不支持这些东西的 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 资源。
推荐阅读
- node.js - 如何从 Kafka 中的特定偏移量获取数据?
- java - 在我尝试访问应用程序时在tomcat 8中成功部署角度js项目构建后,它没有显示空白页面
- javascript - HTML Canvas 的文本未显示在屏幕上
- angular - @azure/msal-angular 注销重定向到应用程序,但应用程序不显示
- ios - 有没有办法在 Swift 中反转动画?
- c - 如何通过串行打印浮点数?
- sql-server - T-SQL:创建存储过程以更新表中的列,其中表和字段作为参数
- angular - 如何检测用户已到达虚拟滚动角度 7 中的列表末尾?
- python - 请求模块是否不从谷歌获取完整数据(网络抓取)
- angular - 无法访问检查变量;它在 html 中显示 [object Object](角度 7)