Welcome to Abdul Malik Ikhsan's Blog

Auto add _links property of HAL Resources into all api service in Apigility

Posted in Tutorial PHP, Zend Framework, Zend Framework 2, Zend Framework 3 by samsonasik on July 10, 2017

If you want to have the _links property value to HAL Resource in apigility api service, for example:

{
    "id": 1,
    "name": "Abdul Malik Ikhsan",
    
    "_links": {
        "self": {
            "href": "http://api.dev/user/1"
        }
    }
}

you can do manually in every api service:

use ZF\ContentNegotiation\ViewModel;
use ZF\Hal\Entity as HalEntity;
use ZF\Hal\Link\Link;

// ...

    public function userAction()
    {
        $halEntity = new HalEntity([
             'id' => 1,
             'name' => 'Abdul Malik Ikhsan',   
        ]);

        $link = $halEntity->getLinks();
        $link->add(Link::factory(
              [
                  'rel' => 'self',
                  'url' => $this->getRequest()->getUriString(),
              ]
        ));

        return new ViewModel([
            'payload' => $halEntity,
        ]);
    }

// ...

You can eliminate that by apply via EventManager’s Shared Manager which attach to Zend\Mvc\Controller\AbstractActionController on dispatch event, like below:

namespace Application;

use Zend\Mvc\Controller\AbstractActionController;
use Zend\Mvc\MvcEvent;
use ZF\Hal\Link\Link;
use ZF\Hal\Plugin\Hal;

class Module
{
    public function onBootstrap(MvcEvent $e)
    {
        $app       = $e->getApplication();
        $sharedEvm = $app->getEventManager()->getSharedManager();

        $sharedEvm->attach(AbstractActionController::class, 'dispatch',
            function($event) use ($sharedEvm) {

                $uri = $event->getRequest()->getUriString();

                $sharedEvm->attach(Hal::class, 'renderEntity', function($event) use ($uri) {
                    $event->getParam('entity')
                          ->getLinks()
                          ->add(Link::factory(
                                [
                                    'rel' => 'self',
                                    'url' => $uri,
                                ]
                            ));
                });

            },
            100
        );

    }

    public function getConfig() { /* */ }
}

On above code, we attach ZF\Hal\Plugin\Hal on renderEntity event which get the ZF\Hal\Entity object from ZF\ContentNegotiation\ViewModel payload property, and apply Link into it via ZF\Hal\Link\Link::factory().

Now, you can eliminate unneeded repetitive codes in all every api services.

Done 😉

Tagged with: , ,