Magento 2 follows a robust MVC (Model-View-Controller) architecture, and controllers play a crucial role in handling user requests and returning responses. When developing a custom module, you may wonder:
- Why do most controllers extend
\Magento\Framework\App\Action\Action
? - Can we implement
\Magento\Framework\App\ActionInterface
instead?
In this article, we will explore both approaches, their pros and cons, and when to use each method.
1️⃣ The Role of Action Controllers in Magento 2
In Magento 2, a controller is responsible for processing HTTP requests and generating a response. Controllers are located in the Controller
folder inside a module and must contain an execute()
method.
For example, a typical controller class looks like this:
namespace Vendor\Module\Controller\Custom;
use Magento\Framework\App\Action\Action;
use Magento\Framework\Controller\ResultFactory;
use Magento\Framework\App\Action\Context;
class Test extends Action
{
public function __construct(Context $context)
{
parent::__construct($context);
}
public function execute()
{
$result = $this->resultFactory->create(\Magento\Framework\Controller\ResultFactory::TYPE_RAW);
$result->setContents('Hello, Magento 2!');
return $result;
}
}
This controller extends \Magento\Framework\App\Action\Action
, which is a common approach in Magento 2 development.
2️⃣ Why Extend \Magento\Framework\App\Action\Action
?
Extending Action
provides multiple advantages:
✅ 1. Dependency Injection (DI) Support
The base Action
class accepts \Magento\Framework\App\Action\Context
in its constructor, which includes commonly used objects like:
RequestInterface
($this->getRequest()
)ResponseInterface
($this->getResponse()
)MessageManagerInterface
($this->messageManager
)
This makes it easier to work with request parameters, responses, and session messages without injecting them manually.
✅ 2. Request & Response Handling
When extending Action
, you automatically get access to:
$this->getRequest(); // Retrieves HTTP request
$this->getResponse(); // Retrieves HTTP response
This helps in processing form submissions, API calls, and more.
✅ 3. Default Execution Flow
Magento’s Action
class is part of its built-in request handling mechanism. Extending it ensures that your controller integrates smoothly into Magento’s event-driven system.
✅ 4. Security Features
For frontend controllers (Magento\Framework\App\Action\Action
under Controller\Frontend
), Magento automatically provides CSRF protection. Using ActionInterface
directly may require additional security handling.
3️⃣ Can We Use \Magento\Framework\App\ActionInterface
Instead?
Yes, but it’s not always recommended. Implementing ActionInterface
means you lose the built-in features of the Action
class, making your code more complex.
Example of a Controller Using ActionInterface
namespace Vendor\Module\Controller\Custom;
use Magento\Framework\App\ActionInterface;
use Magento\Framework\App\RequestInterface;
use Magento\Framework\Controller\ResultFactory;
class Test implements ActionInterface
{
protected $request;
protected $resultFactory;
public function __construct(RequestInterface $request, ResultFactory $resultFactory)
{
$this->request = $request;
$this->resultFactory = $resultFactory;
}
public function execute()
{
$result = $this->resultFactory->create(\Magento\Framework\Controller\ResultFactory::TYPE_RAW);
$result->setContents('Hello, Magento 2!');
return $result;
}
}
Downsides of Using ActionInterface
❌ No automatic DI support – You must manually inject RequestInterface
and ResultFactory
.
❌ Lack of request & response helpers – $this->getRequest()
and $this->getResponse()
are not available.
❌ More boilerplate code – You have to manually handle dependencies, reducing development efficiency.
❌ Missing security features – CSRF protection is not included automatically in frontend controllers.
When Should You Use ActionInterface
?
There are very few cases where implementing ActionInterface
is useful. You may consider it if:
- You only need a minimal controller with a single
execute()
method and don’t need dependencies. - You want full control over dependency injection without inheriting any logic from Magento’s base classes.
However, in 99% of cases, extending Action
is the better and more efficient approach.
4️⃣ Conclusion: Which One Should You Use?
Feature | Extending Action | Implementing ActionInterface |
---|---|---|
Dependency Injection | ✅ Built-in via Context | ❌ Must be handled manually |
Request & Response Helpers | ✅ Available ($this->getRequest() , $this->getResponse() ) | ❌ Not available |
Security (CSRF Protection) | ✅ Provided automatically in frontend controllers | ❌ Must be handled manually |
Boilerplate Code | ✅ Less code, better maintainability | ❌ More manual implementation required |
Best Practice? | ✅ Yes | ❌ Only for specific use cases |
👉 Final Recommendation: Always extend \Magento\Framework\App\Action\Action
unless you have a very specific reason to use ActionInterface
. It simplifies development, reduces boilerplate code, and ensures better integration with Magento’s framework.
📌 Key Takeaways
- Extending
\Magento\Framework\App\Action\Action
is the best practice because it provides built-in request handling, DI support, and security features. - Implementing
ActionInterface
requires more manual work and should only be used in rare cases where full control is necessary. - Magento 2’s MVC architecture benefits from using
Action
, making development faster, cleaner, and more maintainable.
By following these best practices, you can ensure that your Magento 2 modules are built efficiently and aligned with Magento’s framework standards. 🚀