I'm attempting to write a child route for an Apigility Service, and everything routes fine until it comes time to render the _self
link..
GET http://host/api/service/parameter/gui/page
{
"status": 500,
"title": "Unexpected error",
"describedBy": "http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html",
"detail": "Missing parameter \"parameter\"",
"details": {
"code": 0,
"message": "Missing parameter \"parameter\"",
"trace": "#0 /vagrant/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/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/vendor/zendframework/zendframework/library/Zend/Mvc/Router/Http/Part.php(197): Zend\\Mvc\\Router\\Http\\Segment->assemble(Array, Array)\n#3 /vagrant/vendor/zendframework/zendframework/library/Zend/Mvc/Router/Http/TreeRouteStack.php(351): Zend\\Mvc\\Router\\Http\\Part->assemble(Array, Array)\n#4 /vagrant/vendor/zendframework/zendframework/library/Zend/View/Helper/Url.php(100): Zend\\Mvc\\Router\\Http\\TreeRouteStack->assemble(Array, Array)\n#5 [internal function]: Zend\\View\\Helper\\Url->__invoke('parent.rest.s...', Array, Array, true)\n#6 /vagrant/vendor/zfcampus/zf-hal/src/Plugin/Hal.php(610): call_user_func(Object(Zend\\View\\Helper\\Url), 'parent.rest.s...', Array, Array, true)\n#7 /vagrant/vendor/zfcampus/zf-hal/src/Plugin/Hal.php(634): ZF\\Hal\\Plugin\\Hal->fromLink(Object(ZF\\Hal\\Link\\Link))\n#8 /vagrant/vendor/zfcampus/zf-hal/src/Plugin/Hal.php(667): ZF\\Hal\\Plugin\\Hal->fromLinkCollection(Object(ZF\\Hal\\Link\\LinkCollection))\n#9 /vagrant/vendor/zfcampus/zf-hal/src/Plugin/Hal.php(525): ZF\\Hal\\Plugin\\Hal->fromResource(Object(ZF\\Hal\\Entity))\n#10 /vagrant/vendor/zfcampus/zf-hal/src/View/HalJsonRenderer.php(117): ZF\\Hal\\Plugin\\Hal->renderEntity(Object(ZF\\Hal\\Entity))\n#11 /vagrant/vendor/zendframework/zendframework/library/Zend/View/View.php(205): ZF\\Hal\\View\\HalJsonRenderer->render(Object(ZF\\Hal\\View\\HalJsonModel))\n#12 /vagrant/vendor/zendframework/zendframework/library/Zend/Mvc/View/Http/DefaultRenderingStrategy.php(102): Zend\\View\\View->render(Object(ZF\\Hal\\View\\HalJsonModel))\n#13 [internal function]: Zend\\Mvc\\View\\Http\\DefaultRenderingStrategy->render(Object(Zend\\Mvc\\MvcEvent))\n#14 /vagrant/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php(468): call_user_func(Array, Object(Zend\\Mvc\\MvcEvent))\n#15 /vagrant/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php(207): Zend\\EventManager\\EventManager->triggerListeners('render', Object(Zend\\Mvc\\MvcEvent), Array)\n#16 /vagrant/vendor/zendframework/zendframework/library/Zend/Mvc/Application.php(352): Zend\\EventManager\\EventManager->trigger('render', Object(Zend\\Mvc\\MvcEvent))\n#17 /vagrant/vendor/zendframework/zendframework/library/Zend/Mvc/Application.php(327): Zend\\Mvc\\Application->completeRequest(Object(Zend\\Mvc\\MvcEvent))\n#18 /vagrant/public/index.php(38): Zend\\Mvc\\Application->run()\n#19 {main}"
}
}
Looking at the ZF2 MVC documentation, I kind of realize I need to setup a metadata_map entry for my parameter.. but no examples for Apigility exist. I've read hard coding didn't work, even so, this parameter
is dynamic and it's unclear how to do that call properly from module.config.php
'zf-hal' => array(
'metadata_map' => array(
'Parent\\V1\\Rest\\Service\\ServiceEntity' => array(
'entity_identifier_name' => 'parameter',
'route_name' => 'parent.rest.service',
'route_identifier_name' => 'parameter',
'hydrator' => 'Zend\\Stdlib\\Hydrator\\ObjectProperty',
),
'Parent\\V1\\Rest\\Service\\ServiceCollection' => array(
'entity_identifier_name' => 'parameter',
'route_name' => 'parent.rest.service',
'route_identifier_name' => 'parameter',
'is_collection' => true,
),
'Parent\\V1\\Rest\\Gui\\GuiEntity' => array(
'entity_identifier_name' => 'page',
'route_name' => 'parent.rest.service/gui',
'route_identifier_name' => 'gui_page',
'route_params' => array('parameter'), #<------- unknown setting area, needs to get the parent route identifier somehow...
'hydrator' => 'Zend\\Stdlib\\Hydrator\\ObjectProperty',
),
'Parent\\V1\\Rest\\Gui\\GuiCollection' => array(
'entity_identifier_name' => 'page',
'route_name' => 'parent.rest.service/gui',
'route_identifier_name' => 'gui_page',
'route_params' => array('parameter'),
'is_collection' => true,
),
),
),
edit : adding the router configuration
'router' => array(
'routes' => array(
'parent.rest.service' => array(
'type' => 'Segment',
'options' => array(
'route' => '/api/service[/:parameter]',
'defaults' => array(
'controller' => 'Parent\\V1\\Rest\\Service\\Controller',
),
),
'may_terminate' => true,
'child_routes' => array(
'gui' => array(
'type' => 'Segment',
'options' => array(
'route' => '/gui[/:page]',
'defaults' => array(
'controller' => 'Parent\\V1\\Rest\\Gui\\Controller',
),
),
)
),
),
),
),
I have some experience with Apigility, but not with your kind of configuration.
As far as I know it indeed means that the Hal-plugin cannot find a value for your the route_identifier
called parameter
and because of this it cannot render a self link.
In some of your metadata_map
configs (nr 1+2) it seems like it should get the value from the resource:
There is a route with route name:
'route_name' => 'parent.rest.service',
To properly render this route we need a route identifier named parameter
:
'route_identifier_name' => 'parameter',
To get the value for this route identifier we need the property named parameter
from the entity:
'entity_identifier_name' => 'parameter',
Most likely the entity should have data in an array and that array should hold a key named 'parameter' then it will try to get the value that goes with that key.
In another metadata_map
config you set an array of 'static' route params like this:
'route_params' => array('parameter'),
This is incomplete, because you set a route parameter array always with a key and a value. So this should be something like this:
'route_params' => array('parameter' => 'my_value'),
Where my_value
can be a string an integer etc.
I hope this insight can help you a bit. I don't seem to totally see where else it could go wrong.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With