加速Doctrine Driven API

时间:2015-08-06 09:47:27

标签: php api orm doctrine-orm

前言

相当大的php项目。网站与PHP模板。 Php驱动的API。 我们正在使用Doctrine ORM。模型(=实体)以及映射元保持业务逻辑。

模型示例:

class User {
    private $firstName;
    private $lastName;

    public getFullName() {
        return $this->firstName + $this->lastName;
    }
}

此处User类包含两个字段和getFullName(),它们是基于字段值的业务逻辑。

问题:

在API中如何在模型中重用业务逻辑,同时保持高性能。

使用API​​中的doctrine模型不是一种选择。 因为Doctrine(与任何正常的ORM一样)在内存中提取整个对象。 对于API,这是问题(主要是时间)。我们只需要在api中返回有限的字段集。 即使关联是延迟加载,也会在每次使用相应的模型方法时获取它们。 我们有相当多的协会,反过来可以有其他协会等。 当我们处理收集调用时,问题会变得更糟(即使有分页限制)。

示例:

// GET /users
{
    [
        {
             id: 123,
             firstName: John,
             lastName: Doe,
             children: [
                    {
                        id: 456,
                        firstName: Mary,
                        lastName: Doe,
                        friends: [
                             {
                                   {
                                         id: 678,
                                         firstName: Jane,
                                         lastName: The Strawberry
                                   }
                             },
                        ]
                    },
                    ...
             ]
        },
        ... 
    ]
}

这是一个虚拟的例子,但展示了一个问题。

可能的解决方案:

1)Partial objects

在这种情况下,业务逻辑保留在现有模型中,同时仅获取所需的字段。 但它并没有多大帮助,响应时间减少约100毫秒这是不够的。 此外,部分对象使用起来非常危险,在许多ORM中都是禁止使用的,而且Doctrine本身也非常不鼓励使用。

2)原始数组。

我们可以使用dql(甚至是原始的sql)。事情变得快2到3倍(响应时间和记忆)这是好事。 但是,从模型中重用域逻辑会成为一个问题,因为我们正在处理未包含在模型中的纯行。 因此,很明显逻辑必须“提取”到可以在两个模型对象中重用的地方以及处理原始数组结果时。这可以通过一些模式(例如策略模式)来完成。我们现在正在调查, 但它很复杂:(

任何想法/常见做法/想法?

P.S。像“Trow away Doctrine,你的架构很糟糕......”之类的评论被接受:)

0 个答案:

没有答案