← Voltar ao blog

Magento Open Source vs Adobe Commerce: diferenças para devs

Rodrigo Biazzi

O Magento Open Source e o Adobe Commerce compartilham a maior parte do código. Mesmo framework, mesma estrutura de módulos, mesmo checkout, mesmas APIs. O Adobe Commerce adiciona um conjunto de módulos comerciais por cima, além de acesso à infraestrutura cloud e aos serviços SaaS da Adobe. Para o lojista, a pergunta costuma ser sobre funcionalidades e custo de licença. Para o desenvolvedor, a pergunta é outra: o que muda no código, no banco e no fluxo de trabalho, e o que quebra se um código escrito para uma edição roda na outra.

Este artigo fica nessas diferenças que importam para quem desenvolve na 2.4.x. Termos de licença e preços mudam e não são cobertos aqui.

Como as edições são empacotadas

As duas edições são instaladas com Composer a partir do repo.magento.com. O Open Source usa o metapackage magento/product-community-edition. O Adobe Commerce usa o magento/product-enterprise-edition, que puxa os pacotes do Open Source mais os módulos comerciais. Suas access keys decidem quais pacotes você pode baixar.

composer create-project --repository-url=https://repo.magento.com/ \
  magento/project-enterprise-edition=2.4.8 commerce

composer create-project --repository-url=https://repo.magento.com/ \
  magento/project-community-edition=2.4.8 opensource

Ir do Open Source para o Adobe Commerce é um upgrade no mesmo lugar: trocar o metapackage, rodar o Composer e o setup:upgrade. Voltar é muito mais difícil, porque os módulos do Commerce alteram o schema do banco, como explicado abaixo.

Funcionalidades que existem só no Adobe Commerce

Os módulos comerciais cobrem funcionalidades de merchandising, marketing e operação. As que os desenvolvedores mais encontram:

  • Content staging e preview. Mudanças agendadas em produtos, categorias, conteúdo CMS, price rules e cart rules, com preview da loja numa data futura.
  • Suíte B2B. Contas de empresa, shared catalogs, negotiable quotes, purchase orders, quick order e requisition lists, por meio de um pacote de extensão separado. Veja funcionalidades B2B do Adobe Commerce.
  • Customer segments e conteúdo direcionado com base neles.
  • Related product rules, que preenchem listas de related, up sell e cross sell automaticamente.
  • Gift cards, reward points e store credit.
  • Gestão de devoluções (RMA).
  • Catalog permissions para esconder categorias ou preços por grupo de cliente.
  • Private sales e events com convites.
  • Logs de ações do admin e importação e exportação agendadas.
  • Visual merchandiser para posições de produtos na categoria.

O Page Builder já esteve nessa lista, mas faz parte do Open Source desde a 2.4.3. A Adobe também oferece serviços SaaS conectados ao Adobe Commerce, como Live Search e Product Recommendations, que rodam fora da aplicação Magento e são instalados como extensões.

A maior diferença no código: row_id e staging

O content staging precisa manter várias versões da mesma entidade, uma por atualização agendada. Para isso, o Adobe Commerce muda a estrutura de chave primária das entidades com staging. Tabelas como catalog_product_entity, catalog_category_entity, cms_page, cms_block, salesrule e catalogrule ganham uma coluna row_id, além das colunas created_in e updated_in, que definem qual versão está ativa quando. As tabelas de valores EAV de produtos e categorias se ligam ao row_id, não ao entity_id.

No Open Source, as tabelas de valores se ligam ao entity_id. No Adobe Commerce, a mesma query não retorna nada ou retorna a versão errada. Esse é o motivo mais comum de uma extensão de terceiros funcionar no Open Source e falhar no Commerce. Qualquer SQL cru que toque essas tabelas precisa perguntar ao Magento qual coluna usar:

<?php
declare(strict_types=1);

namespace Vendor\Catalog\Model\ResourceModel;

use Magento\Catalog\Api\Data\ProductInterface;
use Magento\Framework\App\ResourceConnection;
use Magento\Framework\EntityManager\MetadataPool;

class ProductValueReader
{
    public function __construct(
        private readonly ResourceConnection $resource,
        private readonly MetadataPool $metadataPool
    ) {
    }

    public function getVarcharValue(int $productId, int $attributeId, int $storeId): ?string
    {
        $metadata = $this->metadataPool->getMetadata(ProductInterface::class);
        $linkField = $metadata->getLinkField();
        $connection = $this->resource->getConnection();

        $select = $connection->select()
            ->from(['e' => $this->resource->getTableName('catalog_product_entity')], [])
            ->join(
                ['v' => $this->resource->getTableName('catalog_product_entity_varchar')],
                "v.$linkField = e.$linkField",
                ['value']
            )
            ->where('e.entity_id = ?', $productId)
            ->where('v.attribute_id = ?', $attributeId)
            ->where('v.store_id = ?', $storeId);

        $value = $connection->fetchOne($select);

        return $value === false ? null : (string) $value;
    }
}

O getLinkField() retorna entity_id no Open Source e row_id no Adobe Commerce, então o mesmo código roda nas duas. No Commerce, a tabela de entidades do catálogo também contém versões futuras de um produto. O framework de staging normalmente adiciona um filtro em created_in e updated_in nas queries de collection, mas um select cru como o de cima pode retornar uma versão agendada. Para qualquer coisa além de uma consulta rápida, prefira repositories e collections, que cuidam disso para você.

Os arquivos de declarative schema também são afetados. Uma foreign key na sua própria tabela que referencia catalog_product_entity.entity_id funciona nas duas edições, porque o entity_id continua existindo. Uma foreign key para uma tabela de valores precisa seguir o link field. Mais sobre arquivos de schema em declarative schema e data patches.

Salvando entidades no Commerce

Como entidades com staging têm versões, salvar um produto por um resource model de baixo nível pode criar linhas inconsistentes no Commerce. Use os service contracts, como o ProductRepositoryInterface, para escritas. Atualizações agendadas são criadas pelas APIs de staging, não definindo datas no produto. Updates diretos em SQL nas tabelas de produto, um atalho que alguns scripts de importação tomam, são arriscados no Commerce pelo mesmo motivo. A camada de serviços está explicada em service contracts e repositories.

Infraestrutura cloud

O Adobe Commerce pode rodar na Adobe Commerce on cloud infrastructure, uma plataforma gerenciada com um jeito próprio de trabalhar:

  • Builds e deploys são conduzidos por Git push e pelo pacote magento/ece-tools.
  • A configuração da aplicação e dos serviços fica em .magento.app.yaml, .magento/services.yaml e .magento/routes.yaml, e o comportamento do deploy em .magento.env.yaml.
  • O filesystem é somente leitura em runtime, fora de alguns mounts graváveis, então tudo que grava em diretórios de código em produção falha.
  • A Fastly é o CDN e o full page cache, com um módulo próprio para snippets de VCL.

Um código que funciona num servidor próprio pode falhar ali porque grava arquivos no lugar errado ou depende de um serviço que não está configurado. O Adobe Commerce também pode ser hospedado por conta própria, e nesse caso nada disso se aplica.

Testando extensões nas duas edições

Se você cria módulos para outras pessoas, ou uma loja pode migrar entre edições, teste nas duas:

  1. Rode testes de integração contra uma instalação Open Source e uma Commerce. As diferenças aparecem em queries, fixtures e declarações de dependência.
  2. Não dependa de módulos do Commerce no composer.json ou no module.xml a menos que o módulo realmente precise deles. Integrações opcionais podem ficar num módulo separado que depende do módulo do Commerce.
  3. Confira plugins em classes em que módulos do Commerce também têm plugin, como cálculo de preço, totais e lógica de grupo de cliente. A ordem de execução pode mudar o comportamento.
  4. Procure no seu código por entity_id em joins com tabelas de catálogo, CMS ou regras. Cada um é um possível bug no Commerce.

Análise estática também ajuda aqui. O PHPStan com a extensão do Magento pega problemas de tipo, mas não o problema do row_id. Veja PHPStan para Magento 2.

Em qual construir

Do ponto de vista do desenvolvedor, o Open Source é mais simples: um ID por entidade, sem camada de staging, menos módulos na stack. O Adobe Commerce faz sentido quando o negócio usa as funcionalidades dele, principalmente staging, B2B ou customer segments, e está pronto para bancar o trabalho que elas exigem. Comprar o Commerce por causa de uma funcionalidade que uma única extensão poderia dar no Open Source é um erro comum. O oposto também é comum: reconstruir B2B ou staging no Open Source com várias extensões que nunca funcionam bem juntas.

FAQ

O código do Magento Open Source e do Adobe Commerce é o mesmo?

O framework do core e a maioria dos módulos são os mesmos. O Adobe Commerce adiciona módulos comerciais por cima, e alguns deles, como o content staging, mudam a estrutura de banco das tabelas de catálogo e de conteúdo.

Por que uma extensão funciona no Open Source mas falha no Adobe Commerce?

O motivo mais comum é SQL cru que faz join de tabelas de valores EAV em entity_id. No Adobe Commerce essas tabelas se ligam por row_id por causa do content staging. Use o MetadataPool para obter o link field.

O Page Builder existe só no Adobe Commerce?

Não. O Page Builder faz parte do Magento Open Source desde a 2.4.3.

Posso voltar do Adobe Commerce para o Open Source?

É possível, mas não é uma simples troca de pacote. A estrutura de row_id, os dados de staging e as tabelas exclusivas do Commerce precisam ser migrados ou removidos, então planeje como um projeto de migração.

Atendo como freelancer em Magento e Adobe Commerce, em qualquer das duas edições. Se você precisa de ajuda com isso, fale comigo.

Artigos relacionados