Introduction
Shopware 6.7 represents a significant evolution in the platform's architecture, introducing new concepts and refining existing ones to provide developers with more flexibility and power. Among the most important decisions developers face is choosing between developing applications (Apps) or plugins for their Shopware solutions. Both approaches offer distinct advantages and are suited for different use cases. This comprehensive guide will explore the technical differences, implementation details, and decision-making factors that will help you determine which approach is best for your specific requirements.
What Are Apps and Plugins in Shopware 6.7?
In Shopware 6.7, both apps and plugins serve as extension mechanisms, but they operate at different levels of abstraction and offer varying degrees of functionality and integration capabilities.
Plugins
Plugins are traditional extensions that integrate directly into the Shopware platform. They're built using PHP and leverage the existing Symfony framework components. Plugins can modify core functionality, add new features, or customize existing behavior through hooks and events.
Apps
Apps represent a newer, more modern approach to extension development in Shopware 6.7. They're essentially microservices that communicate with the Shopware platform through a RESTful API interface. This architectural shift provides better isolation, scalability, and security compared to traditional plugins.
Technical Architecture Differences
Plugin Architecture
Plugins in Shopware 6.7 follow a traditional monolithic approach where they're loaded into the main application context. The plugin structure includes:
MyPlugin/
├── src/
│ ├── Resources/
│ │ ├── config/
│ │ ├── migration/
│ │ └── snippet/
│ ├── Controller/
│ ├── Event/
│ ├── Service/
│ └── Subscriber/
├── composer.json
└── manifest.xml
Plugins register services through the Symfony DIC (Dependency Injection Container) and can hook into various lifecycle events using Symfony events.
App Architecture
Apps in Shopware 6.7 are built as separate services that communicate with the Shopware platform via HTTP APIs. The app structure is more streamlined:
MyApp/
├── src/
│ ├── Resources/
│ │ ├── config/
│ │ └── snippet/
│ ├── Controller/
│ └── Service/
├── composer.json
└── manifest.xml
Apps communicate through the App API, which includes endpoints for configuration management, webhook handling, and data synchronization.
Implementation Examples
Plugin Development Example
// src/MyPlugin/src/Subscriber/ProductSubscriber.php
<?php declare(strict_types=1);
namespace MyPlugin\Subscriber;
use Shopware\Core\Checkout\Order\OrderEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RequestStack;
class ProductSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
OrderEvents::ORDER_STATE_CHANGED => 'onOrderStateChanged',
];
}
public function onOrderStateChanged(OrderStateChangedEvent $event): void
{
// Custom logic when order state changes
$order = $event->getOrder();
// Process the order change
}
}
App Development Example
// src/MyApp/src/Controller/AppController.php
<?php declare(strict_types=1);
namespace MyApp\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Annotation\Route;
#[Route('/app', defaults: ['_routeScope' => ['api']])]
class AppController extends AbstractController
{
#[Route('/webhook', methods: ['POST'])]
public function handleWebhook(): JsonResponse
{
// Handle webhook events from Shopware
return new JsonResponse(['status' => 'success']);
}
}
Configuration and Installation
Plugin Configuration
Plugins require a manifest.xml file that defines their metadata:
<?xml version="1.0" encoding="UTF-8"?>
<manifest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/shopware/platform/master/src/Core/System/SystemConfig/Schema/manifest.xsd">
<meta>
<name>MyPlugin</name>
<version>1.0.0</version>
<author>Your Company</author>
</meta>
<services>
<service id="MyPlugin\Subscriber\ProductSubscriber"/>
</services>
</manifest>
App Configuration
Apps use a more sophisticated configuration approach through the manifest.xml:
<?xml version="1.0" encoding="UTF-8"?>
<manifest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/shopware/platform/master/src/Core/System/SystemConfig/Schema/manifest.xsd">
<meta>
<name>MyApp</name>
<version>1.0.0</version>
<author>Your Company</author>
</meta>
<config>
<input-field type="text">
<name>apiKey</name>
<label>API Key</label>
</input-field>
</config>
<webhooks>
<webhook name="order.created" url="/app/webhook"/>
</webhooks>
</manifest>
Performance Considerations
Plugin Performance
Plugins execute within the same process as the main Shopware application, which can lead to performance benefits in terms of reduced network overhead and faster execution times. However, this tight coupling also means that plugin issues can potentially impact the entire platform.
// Plugin execution context
class PluginService
{
public function processOrder(Order $order): void
{
// Direct database access
$this->connection->executeQuery('SELECT * FROM order WHERE id = ?', [$order->getId()]);
// Immediate execution
$this->eventDispatcher->dispatch(new OrderProcessedEvent($order));
}
}
App Performance
Apps operate as separate services, introducing network overhead but providing better isolation and scalability. This approach is particularly beneficial for resource-intensive operations or when you need to handle high traffic loads.
// App execution context
class AppService
{
public function processOrder(Order $order): void
{
// HTTP request to app service
$response = $this->httpClient->request('POST', 'https://app.example.com/process-order', [
'json' => ['orderId' => $order->getId()]
]);
// Asynchronous processing
$this->queue->push(new ProcessOrderJob($order->getId()));
}
}
Security Implications
Plugin Security
Plugins execute with the same privileges as the main application, which can be both a benefit and a risk. While they have direct access to all system resources, security vulnerabilities in plugins can potentially compromise the entire platform.
App Security
Apps operate in a more isolated environment, reducing the attack surface. They communicate through defined APIs with strict authentication mechanisms, providing better security boundaries between the app and the main platform.
Deployment and Updates
Plugin Deployment
Plugin updates require the standard Shopware update process, which involves:
- Uploading new plugin files
- Clearing caches
- Rebuilding the application
- Potential downtime during update
# Plugin update workflow
php bin/console plugin:update MyPlugin
php bin/console cache:clear
php bin/console database:dump
App Deployment
App updates follow a more modern deployment approach:
- Deploy app service to separate infrastructure
- Update configuration in Shopware
- No platform downtime required
- Rollback capabilities through version management
When to Choose Each Approach
Choose Plugins When:
- Performance is Critical: You need direct access to database and system resources without network overhead
- Simple Customizations: Implementing minor modifications or extensions to existing functionality
- Tight Integration: Requires deep integration with core Shopware events and services
- Development Speed: Faster development cycles due to direct execution context
Choose Apps When:
- Scalability Requirements: Need to handle high traffic loads or resource-intensive operations
- Separation of Concerns: Want to isolate functionality from the main platform
- Microservices Architecture: Following modern architecture patterns with service isolation
- Third-party Integration: Building solutions that integrate with external systems
- Team Collaboration: Multiple teams working on different components without conflicts
Best Practices and Recommendations
Plugin Best Practices
- Use Events Properly: Leverage Shopware's event system for clean integration points
- Implement Caching: Use Symfony's caching mechanisms to optimize performance
- Follow Naming Conventions: Maintain consistent naming across your plugin structure
- Handle Dependencies Carefully: Manage Composer dependencies properly
App Best Practices
- Design for Isolation: Structure apps to be self-contained and resilient
- Implement Proper Error Handling: Handle network failures gracefully
- Use Webhooks Efficiently: Design webhook handlers to process events asynchronously
- Monitor Performance: Implement proper logging and monitoring for your app services
Conclusion
The choice between app and plugin development in Shopware 6.7 ultimately depends on your specific requirements, performance needs, and architectural preferences. Plugins offer direct integration and better performance for simple extensions, while apps provide better scalability, isolation, and modern development practices.
Understanding these technical differences is crucial for making informed decisions that will impact your project's long-term success. As Shopware 6.7 continues to evolve, both approaches will likely see further enhancements, but the fundamental architectural choices remain important considerations for any developer working within this platform.
Whether you're building a simple custom feature or a complex integration solution, evaluating these factors will help you choose the right approach for your specific use case and ensure optimal performance, maintainability, and scalability of your Shopware extensions.