Spryker-Entwickler über Shopware

In den letzten Jahren habe ich hauptsächlich mit Spryker gearbeitet. Da ich mich jetzt schwerpunktmäßig mit Shopware beschäftige, schaue ich mir auch den Code genauer an. Als die ersten Videos Shopware für Entwickler gesehen habe, ist mir aufgefallen, dass die Developer-Experience bei Shopware verbesserungswürdig ist, denn ist gibt einiges and "Duplicate-Logic", die man eigentlich vermeiden kann.

Entities

Shopware nutzt nicht Doctrine oder eine eigene ORM-Library, was verständlich ist und soweit auch gut ist, denn eine eigene Lösung, die zugeschnitten auf eigne Bedürfnisse ist, kann viel schneller und effizienter sein.
Shopware nutzt eine EntityDefinition Klasse, in der die Properties der Entities definiert werden. Eine Entity Klasse sieht wie folgt aus.


class ExampleDefinition extends EntityDefinition
{
    public const ENTITY_NAME = 'swag_example';

    public function getEntityName(): string
    {
        return self::ENTITY_NAME;
    }

    protected function defineFields(): FieldCollection
    {
        return new FieldCollection([
            (new IdField('id', 'id'))->addFlags(new Required(), new PrimaryKey()),
            (new StringField('name', 'name')),
            (new StringField('description', 'description')),
            (new BoolField('active', 'active'))
        ]);
    }
}

In der Methode defineFields erkennt man sofort, dass die Properties und die dazugehörigen Felder in der Datenbank definiert werden.
Man braucht natürlich auch eine EntityClass, die wie folgt aussieht.


class ExampleEntity extends Entity
{
    use EntityIdTrait;

    protected ?string $name;

    protected ?string $description;

    protected bool $active;

    public function getName(): ?string
    {
        return $this->name;
    }

    public function setName(?string $name): void
    {
        $this->name = $name;
    }

    public function getDescription(): ?string
    {
        return $this->description;
    }

    public function setDescription(?string $description): void
    {
        $this->description = $description;
    }

    public function isActive(): bool
    {
        return $this->active;
    }

    public function setActive(bool $active): void
    {
        $this->active = $active;
    }
}

Genau hier ist das Problem, denn wir haben dieselbe Information an zwei Stellen, denn die Entity Klasse könnte man anhand der EntityDefinition Klasse generieren. Das ist aber leidet nicht der Fall, zumindest habe ich dafür keinen Console Command gefunden.
Die Klasse muss manuell angelegt werden die Properties müssen auch manuell definiert werden, zumindest nach dem jetzigen Stand (13.02.2023).

Migration

Natürlich braucht man zusätzlich eine Klasse für die Datenbank-Migration und die sieht wie folgt aus.


class Migration1611664789Example extends MigrationStep
{
    public function getCreationTimestamp(): int
    {
        return 1611664789;
    }

    public function update(Connection $connection): void
    {
        $sql = <<<SQL
                CREATE TABLE IF NOT EXISTS `swag_example` (
                `id` BINARY(16) NOT NULL,
                `name` VARCHAR(255) COLLATE utf8mb4_unicode_ci,
                `description` VARCHAR(255) COLLATE utf8mb4_unicode_ci,
                `active` TINYINT(1) COLLATE utf8mb4_unicode_ci,
                `created_at` DATETIME(3) NOT NULL,
                `updated_at` DATETIME(3),
                PRIMARY KEY (`id`)
                )
                ENGINE = InnoDB
                DEFAULT CHARSET = utf8mb4
                COLLATE = utf8mb4_unicode_ci;
                SQL;
                $connection->executeStatement($sql);
    }

    public function updateDestructive(Connection $connection): void
    {
    }
}

Das macht das Problem noch schlimmer, die Klasse kann man zwar mit einem Console Command generieren lassen, aber nicht die SQL-Query, die muss man manuell schreiben. Jetzt haben wir die gleiche Information an drei Stellen. Das mach die Entwicklung langsamer und fehleranfälliger. Die Migration kann man ebenfalls anhand der Information in EntityDefinition class generieren.

Ich hoffe, dass das Shopware-Team sich auch um dieses Thema kümmert und meine Wünsche bei den nächsten Updates berücksicht.



Value3 GmbH, Essen