HTTP Controller

HTTP Controllers are the equivalent to PSR15 middleware classes, are what facilitate the processing of all incoming HTTP requests to the system, and are all located within the /src/HttpControllers/ directory. You may create a new HTTP controller by using the create http-controller CLI command, such as:

apex create http-controller <PACKAGE> <PATH> [--route <ROUTE>]

apex create http-controller my-shop Shop/Payment --route payment/:order_id

Using the above example, a new file will be created at /src/HttpControllers/Shop/Payment.php which is a PSR15 middleware class, which contains one process() method that must return a PSR7 ResponseInterface object that is subsequently output to the client. The optional --route flag was also defined, and if you look within the /boot/routes.yml file, you will see a new entry for, "'payment/:order_id': Shop\Payment".

You should never manually create HTTP controllers, and instead only ever create them with the above CLI command. This is because doing so wil register the HTTP controller within the /etc/<PACKAGE>/registry.yml file, ensuring it is included when the package is published to the repository.

An optional --route flag is also available, and if defined contains the value of the route to add into the /boot/routes.yml file. You should always include this if necessary, because it will also be registered within the /etc/<PACKAGE>/registry.yml file so during installation on other machines the route will be automatically added to the /boot/routes.yml file.

Example

Using the above example, upon visiting the URL http://localhost/payment/<ORDER_ID> the HTTP controller at /etc/HttpControllers/Shop/Payment.php will be executed to handle the request. Below is an example Payment.php class.

<?php
declare(strict_types = 1);

namespace App\HttpControllers\Shop;

use Apex\Svc\{App, View};
use App\MyShop\Models\Order;
use Nyholm\Psr7\Response;
use Psr\Http\Message\{ServerRequestInterface, ResponseInterface};
use Psr\Http\Server\{MiddlewareInterface, RequestHandlerInterface};

/**
 * Http Controller - ~alias~
 */
class Payment implements MiddlewareInterface
{

    #[Inject(View::class)]
    private View $view;

    /**
     * Process request
     */
    public function process(ServerRequestInterface $request, RequestHandlerInterface $app): ResponseInterface
    {

        // Get order id
        $order_id = $app->pathParam('order_id');

        // Get order
        if (!$order = Order::whereId($order_id)) {
            $html = $this->view->render('404');
            return new Response(404, [], $html);
        }

        // Display html
        $this->view->assign('order', $order->toArray());
        $html = $this->view->render('shop/pay');
        return new Response(200, [], $html);
    }

}

Some notes on the above class:

  • Apex\Svc\View is injected via attribute based injection.
  • The order id# provided as a dynamic path parameter is retrived using the App::pathParam function.
  • Tries to retrive the order from the database, and if it doesn't exist, returns a 404 page not found.
  • Renders the payment view, and returns it for output to the browser.