laminas-api-tools / api-tools

Laminas API Tools module for Laminas
https://api-tools.getlaminas.org/documentation
BSD 3-Clause "New" or "Revised" License
37 stars 18 forks source link

Attaching to HAL plugin event manager causes apigility admin to fail to load existing API's #58

Open michalbundyra opened 4 years ago

michalbundyra commented 4 years ago

After attaching a listener to HAL plugin event manager and trying to edit API's in /apigility/ui#/api,and clicking on an existing API, it wont load. When I comment out the onBootstrap() method in Module.php, the existing API's load normally.

/**
 * Attach the image links listener to the hal render entity event
 *
 * @param MvcEvent $e
 */
public function onBootstrap(MvcEvent $e)
{
    $app = $e->getTarget();
    $services = $app->getServiceManager();
    $helpers  = $services->get('ViewHelperManager');
    $hal      = $helpers->get('Hal');

    $listener = new ImageLinksListener();
    $hal->getEventManager()->attach('renderEntity', function () { return; });
}

The call to /apigility/api/module/FileApi/rest?version=1 fails with this response:

{
    "status":500,
    "title":"Unexpected error",
    "describedBy":"http:\/\/www.w3.org\/Protocols\/rfc2616\/rfc2616-sec10.html",
    "detail":"Missing parameter \"name\"",
    "details":{
        "code":0,
        "message":"Missing parameter \"name\"",
        "trace":"#0 \/vagrant_web\/vendor\/zendframework\/zendframework\/library\/Zend\/Mvc\/Router\/Http\/Segment.php(313): Zend\\Mvc\\Router\\Http\\Segment->buildPath(Array, Array, true, true, Array)\n#1 \/vagrant_web\/vendor\/zendframework\/zendframework\/library\/Zend\/Mvc\/Router\/Http\/Segment.php(409): Zend\\Mvc\\Router\\Http\\Segment->buildPath(Array, Array, false, true, Array)\n#2 \/vagrant_web\/vendor\/zendframework\/zendframework\/library\/Zend\/Mvc\/Router\/Http\/Part.php(197): Zend\\Mvc\\Router\\Http\\Segment->assemble(Array, Array)\n#3 \/vagrant_web\/vendor\/zendframework\/zendframework\/library\/Zend\/Mvc\/Router\/Http\/TreeRouteStack.php(330): Zend\\Mvc\\Router\\Http\\Part->assemble(Array, Array)\n#4 \/vagrant_web\/vendor\/zendframework\/zendframework\/library\/Zend\/Mvc\/Router\/Http\/Part.php(210): Zend\\Mvc\\Router\\Http\\TreeRouteStack->assemble(Array, Array)\n#5 \/vagrant_web\/vendor\/zendframework\/zendframework\/library\/Zend\/Mvc\/Router\/Http\/TreeRouteStack.php(330): Zend\\Mvc\\Router\\Http\\Part->assemble(Array, Array)\n#6 \/vagrant_web\/vendor\/zendframework\/zendframework\/library\/Zend\/Mvc\/Router\/Http\/Part.php(210): Zend\\Mvc\\Router\\Http\\TreeRouteStack->assemble(Array, Array)\n#7 \/vagrant_web\/vendor\/zendframework\/zendframework\/library\/Zend\/Mvc\/Router\/Http\/TreeRouteStack.php(351): Zend\\Mvc\\Router\\Http\\Part->assemble(Array, Array)\n#8 \/vagrant_web\/vendor\/zendframework\/zendframework\/library\/Zend\/View\/Helper\/Url.php(100): Zend\\Mvc\\Router\\Http\\TreeRouteStack->assemble(Array, Array)\n#9 [internal function]: Zend\\View\\Helper\\Url->__invoke('zf-apigility\/ap...', Array, Array, true)\n#10 \/vagrant_web\/vendor\/zfcampus\/zf-hal\/src\/Plugin\/Hal.php(610): call_user_func(Object(Zend\\View\\Helper\\Url), 'zf-apigility\/ap...', Array, Array, true)\n#11 \/vagrant_web\/vendor\/zfcampus\/zf-hal\/src\/Plugin\/Hal.php(634): ZF\\Hal\\Plugin\\Hal->fromLink(Object(ZF\\Hal\\Link\\Link))\n#12 \/vagrant_web\/vendor\/zfcampus\/zf-hal\/src\/Plugin\/Hal.php(667): ZF\\Hal\\Plugin\\Hal->fromLinkCollection(Object(ZF\\Hal\\Link\\LinkCollection))\n#13 \/vagrant_web\/vendor\/zfcampus\/zf-hal\/src\/Plugin\/Hal.php(440): ZF\\Hal\\Plugin\\Hal->fromResource(Object(ZF\\Hal\\Collection))\n#14 \/vagrant_web\/vendor\/zfcampus\/zf-hal\/src\/View\/HalJsonRenderer.php(123): ZF\\Hal\\Plugin\\Hal->renderCollection(Object(ZF\\Hal\\Collection))\n#15 \/vagrant_web\/vendor\/zendframework\/zendframework\/library\/Zend\/View\/View.php(205): ZF\\Hal\\View\\HalJsonRenderer->render(Object(ZF\\Hal\\View\\HalJsonModel))\n#16 \/vagrant_web\/vendor\/zendframework\/zendframework\/library\/Zend\/Mvc\/View\/Http\/DefaultRenderingStrategy.php(102): Zend\\View\\View->render(Object(ZF\\Hal\\View\\HalJsonModel))\n#17 [internal function]: Zend\\Mvc\\View\\Http\\DefaultRenderingStrategy->render(Object(Zend\\Mvc\\MvcEvent))\n#18 \/vagrant_web\/vendor\/zendframework\/zendframework\/library\/Zend\/EventManager\/EventManager.php(468): call_user_func(Array, Object(Zend\\Mvc\\MvcEvent))\n#19 \/vagrant_web\/vendor\/zendframework\/zendframework\/library\/Zend\/EventManager\/EventManager.php(207): Zend\\EventManager\\EventManager->triggerListeners('render', Object(Zend\\Mvc\\MvcEvent), Array)\n#20 \/vagrant_web\/vendor\/zendframework\/zendframework\/library\/Zend\/Mvc\/Application.php(352): Zend\\EventManager\\EventManager->trigger('render', Object(Zend\\Mvc\\MvcEvent))\n#21 \/vagrant_web\/vendor\/zendframework\/zendframework\/library\/Zend\/Mvc\/Application.php(327): Zend\\Mvc\\Application->completeRequest(Object(Zend\\Mvc\\MvcEvent))\n#22 \/vagrant_web\/public\/index_zf2.php(47): Zend\\Mvc\\Application->run()\n#23 {main}"
    }
}

Originally posted by @pdizz at https://github.com/zfcampus/zf-apigility/issues/79

michalbundyra commented 4 years ago

I also have the same problem. This is my code(From aligility documentation https://apigility.org/documentation/modules/zf-hal) public function onBootstrap($e) { $app = $e->getTarget(); $services = $app->getServiceManager(); $helpers = $services->get('ViewHelperManager'); $hal = $helpers->get('Hal'); // The HAL plugin's EventManager instance does not compose a SharedEventManager, // so you must attach directly to it. $hal->getEventManager()->attach('renderEntity', array($this, 'onRenderEntity')); } public function onRenderEntity($e) { $entity = $e->getParam('entity'); if (! $entity->entity instanceof SomeTypeIHaveDefined) { // do nothing return; } // Add a "describedBy" relational link $entity->getLinks()->add(\ZF\Hal\Link\Link::factory(array( 'rel' => 'describedBy', 'route' => array( 'name' => 'my/api/docs', ), ))); }


Originally posted by @nebero at https://github.com/zfcampus/zf-apigility/issues/79#issuecomment-67747424

michalbundyra commented 4 years ago

Same problem here.

Instead of

$app = $e->getTarget();
$services = $app->getServiceManager();
$helpers = $services->get('ViewHelperManager');
$hal = $helpers->get('Hal');
$hal->getEventManager()->attach('renderEntity', array($this, 'onRenderEntity'));

use

$app = $e->getTarget();
$services = $app->getServiceManager();
$sharedEvents = $services->get('SharedEventManager');
$sharedEvents->attach('ZF\Hal\Plugin\Hal', 'renderEntity', array($this, 'onRenderEntity'));

(from https://groups.google.com/a/zend.com/forum/#!msg/apigility-users/p4nm3scFxJM/D9ZjUqECYWUJ)


Originally posted by @gaco79 at https://github.com/zfcampus/zf-apigility/issues/79#issuecomment-72107723

michalbundyra commented 4 years ago

Using the SharedEventManager in the way described by @gaco79 from the Google Groups thread fixed the problem resulting in the error message:

Missing parameter \"name\"

++ for solution.


Originally posted by @ashireman at https://github.com/zfcampus/zf-apigility/issues/79#issuecomment-103691682

michalbundyra commented 4 years ago

+1 for solution


Originally posted by @danbroooks at https://github.com/zfcampus/zf-apigility/issues/79#issuecomment-176496552