【问题标题】:Symfony: Lazy-load a relation from an APISymfony:从 API 延迟加载关系
【发布时间】:2019-05-09 05:14:06
【问题描述】:

我正在寻找从 API 中延迟加载与实体的关系的最佳方法。

场景 我有一个 Symfony 4 应用程序,它由一个使用 Doctrine 的数据库支持,并且在该数据库中我有许多表,包括 Customer。

我还可以访问包含与该客户相关的不同数据的 API,例如发票、帐户、产品、账单。

我需要显示有关客户的数据的分页列表,其中包含来自客户和 API 查询结果的值。

到目前为止,我的解决方案是为 API 中的每个相关实体在 Customer 实体上创建一个属性,然后我有一个 EntityLoadListener 类来侦听 PostLoad 事件生命周期事件。当它被触发时,它会检查实体是否是客户,如果是,它会从 API 加载结果并更新关系:

// customer is the customer entity
// the api call here returns a collection full of invoice entities
$invoices = $this->api->getInvoicesForAccount($customer->getAccountCode());

// get the name of the property to set on the entity
$propertyName = 'apiInvoices';

// set the property on the entity
$relationProp = $em->getClassMetadata($class)
  ->reflClass->getProperty($propertyName);
$relationProp->setAccessible(true);
$relationProp->setValue($entity, $invoices);

这可行,但是当加载大量客户时,它很慢。如果我不需要显示发票数据,我宁愿不从 API 加载数据。有没有更好的方法来实现这一点,我只在为 getApiInvoices 调用 Customer getter 时查询 API(即延迟加载)?

【问题讨论】:

  • 这个问题比较模糊,所以我会投票接近。如果没有更多细节,找到一个好的解决方案只是猜测工作。即使有更多信息,它也会非常固执己见。一项改进可能是拥有一个 API 端点,您可以在其中一次获得多张发票,因此您无需发出 n 请求,只需执行 1 次,然后合并两个结果集。如果要限制查询量,可以通过将发票数据与 getter 结合来延迟加载发票数据,而不是在加载后直接加载。也许在后台加载这些发票并将它们存储在某个地方也是一种选择

标签: symfony doctrine symfony4 api-platform.com


【解决方案1】:

我相信 APIP 默认使用预先加载。您可以通过在 yaml 文件中配置来使用延迟加载

# api/config/packages/api_platform.yaml
api_platform:
    eager_loading:
        force_eager: false

或在资源和操作级别:

<?php
// api/src/Entity/User.php

namespace App\Entity;

use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ApiResource(attributes={"force_eager"=false})
 * @ORM\Entity
 */
class User
{
    /**
     * @var Address
     *
     * @ORM\ManyToOne(targetEntity="Address", fetch="EAGER")
     */
    public $address;

    /**
     * @var Group[]
     *
     * @ORM\ManyToMany(targetEntity="Group", inversedBy="users")
     * @ORM\JoinTable(name="users_groups")
     */
    public $groups;

    // ...
}

https://api-platform.com/docs/core/performance/#force-eager

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-11
    • 2019-10-02
    • 1970-01-01
    • 2012-03-13
    • 1970-01-01
    • 1970-01-01
    • 2015-06-25
    相关资源
    最近更新 更多