给出了以下示例:
我想用API平台实现一个学生报告端点。
api/报告/学生
我有以下表:
学生
id,
name,
address发票
id,
description,
amount,
status,
student_id我想使用API端点返回以下信息:
{
data: [
student_id: 1,
student_name: john,
outstanding_amount: 200 (Total of unpaid bill)
],
[
student_id: 2,
student_name: mike,
outstanding_amount: 300 (Total of unpaid bill)
]
}只是想知道用API (https://api-platform.com)为报表编写API端点的最佳实践是什么。
报表端点需要排序、连接表和分页等。
通过API平台实现这一目标的最佳实践是什么?这是我们可以通过GraphQL实现的,还是需要将其与控制器操作绑定以完成此操作?
谢谢。
发布于 2018-11-29 07:48:35
事实上,假设您已经安装了Core,那么在API平台中您就有了所需的一切。
排序
对于排序,如果您查看过滤器部分,可以使用一个名为阶滤波器的过滤器,它基本上是一个排序过滤器。
==========
分页
在使用分页时,您有很多可用的特性。可以控制每页的项数,也可以为特定资源启用/禁用分页。
==========
连接表
据我所知,您需要从数据库中为您的端点设置一些自定义结果集,例如执行联接。创建自定义原则过滤器应该可以帮助您实现这一目标。
==========
此外,为了获得更大的灵活性,可以使用自定义控制器动作。正如德布鲁曼所说,我认为在这方面也没有任何官方的最佳做法。你只需使用可用的功能。当然,您也可以使用GraphQL,但老实说,我从未使用过它。据我所见,它似乎是一个强大的工具。这取决于你。
发布于 2020-12-05 15:46:13
可能起作用的最简单的解决方案:
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Serializer\Annotation\Groups;
use ApiPlatform\Core\Annotation\ApiFilter;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\OrderFilter;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
/**
* @ApiResource(
* normalizationContext={"groups"={"student:read"}},
* attributes={"order"={"name", "address"}},
* itemOperations={
* "get",
* "put",
* "delete"
* },
* collectionOperations={
* "get",
* "post",
* "get_report"={
* "method"="GET",
* "path"="/students/report",
* "normalization_context"={"groups"={"student:report"}}
* }
* }
* )
* @ApiFilter(OrderFilter::class)
* @ORM\Entity
*/
class Student
{
/**
* @var int
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
* @Groups({"student:report"})
*/
public $id;
/**
* @var string
* @ORM\Column
* @Assert\NotBlank
* @Assert\Length(max=255)
* @Groups({"student:read", "student:report"})
*/
public $name;
/**
* @var string|null
* @ORM\Column(nullable=true)
* @Assert\Length(max=255)
* @Groups({"student:read"})
*/
public $address;
/**
* @var Collection
* @ORM\OneToMany(targetEntity="App\Entity\Invoice", mappedBy="student")
* @Groups({"student:read"})
*/
public $invoices;
public function __construct()
{
$this->invoices = new ArrayCollection();
}
/**
* @return int|float
* @Groups({"student:report"})
*/
public function getOutstandingAmount()
{
$result = 0;
foreach ($this->invoices as $invoice) {
if ($invoice->getStatus() == Invoice::STATUS_OUTSTANDING) {
$result += $invoice->getAmount();
}
}
return $result;
}
}输出中的属性名称不会以student_作为前缀,如果需要,请尝试DTO's。
当然,拥有私有属性和获取器(Setter)会更好,但这不是最简单的解决方案;)
https://stackoverflow.com/questions/53530076
复制相似问题