In Magento 2, controllers are responsible for handling HTTP requests and generating responses. Controllers are essential for building custom functionality in both the frontend and adminhtml (backend) areas.
📂 Where Are Controllers Located?
Controllers are placed inside:
Controller/directory in your module- Subfolders: 
FrontendandAdminhtml 
app/code/Bcn/HelloWorld/Controller/Index/Hello.php app/code/Bcn/HelloWorld/Controller/Adminhtml/Index/Hello.php
—
🛣️ Step 1: Define a Route
Create routes.xml in the etc/frontend or etc/adminhtml folder.
—
📑 Step 2: Create a Frontend Controller
The following controller responds to the URL: /helloworld/index/hello
// Controller/Index/Hello.php
namespace Bcn\HelloWorld\Controller\Index;
use Magento\Framework\App\Action\Action;
use Magento\Framework\App\Action\Context;
use Magento\Framework\Controller\ResultFactory;
class Hello extends Action
{
    public function __construct(Context $context)
    {
        parent::__construct($context);
    }
    public function execute()
    {
        $result = $this->resultFactory->create(ResultFactory::TYPE_RAW);
        $result->setContents("Hello from Bcn_HelloWorld frontend controller!");
        return $result;
    }
}
  
—
🔐 Step 3: Create an Adminhtml Controller
The following controller will be available in the admin panel at: /admin/helloworld/index/hello
// Controller/Adminhtml/Index/Hello.php
namespace Bcn\HelloWorld\Controller\Adminhtml\Index;
use Magento\Backend\App\Action;
use Magento\Backend\App\Action\Context;
use Magento\Framework\Controller\ResultFactory;
class Hello extends Action
{
    public function __construct(Context $context)
    {
        parent::__construct($context);
    }
    public function execute()
    {
        $result = $this->resultFactory->create(ResultFactory::TYPE_RAW);
        $result->setContents("Hello from Bcn_HelloWorld admin controller!");
        return $result;
    }
    protected function _isAllowed()
    {
        return true; // Use ACL in production
    }
}
  
—
⚙️ Result Types in Magento 2
TYPE_PAGE– for full HTML pagesTYPE_RAW– for plain textTYPE_JSON– for JSON responsesTYPE_REDIRECT– for redirects
—
📌 Summary
- Frontend controllers respond to public URLs
 - Adminhtml controllers are used for backend features
 - Use 
routes.xmlto define front names - Always include a secure 
_isAllowed()method in admin controllers 
Controllers are the starting point for any request-based logic. Next, you can integrate Models and Blocks to build dynamic responses.