Skip to content

Instantly share code, notes, and snippets.

@ezimuel
Created May 20, 2014 15:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ezimuel/e2b528ba160197d0c773 to your computer and use it in GitHub Desktop.
Save ezimuel/e2b528ba160197d0c773 to your computer and use it in GitHub Desktop.
RPC with HAL JSON
<?php
namespace Test\V1\Rpc\Test;
use Zend\Mvc\Controller\AbstractActionController;
use ZF\ContentNegotiation\ViewModel;
use ZF\Hal\Entity;
use ZF\Hal\Link\Link;
class TestController extends AbstractActionController
{
public function testAction()
{
$id = 1;
$data = array ( 'name' => 'Enrico Zimuel', 'id' => $id );
$entity = new Entity($data, $id);
$entity->getLinks()->add(Link::factory(array(
'rel' => 'contacts',
'route' => array(
'name' => 'test.rest.user',
)
)));
return new ViewModel(array(
'payload' => $entity
));
}
}
@weierophinney
Copy link

I figured out why this has no self relational link!

In ZF\Rest\Rest\Controller, we always call the createEntity() method of the HAL plugin -- which injects the self relational link! Since you're not doing that here, no such link is created.

I discovered this when looking into another issue reported this week, and I'm strongly considering moving the link injection to renderEntity() and potentiallyrenderCollection()`.

@weierophinney
Copy link

@ezimuel In reading up on HAL and looking through our Hal plugin, two things:

  • The "self" relational link is not strictly required, just strongly recommended (a SHOULD in IETF parlance, but not a MUST). As such, we do not, and should not, inject a self relational link for entities created in RPC controllers, and instead leave it up to the user whether or not they want to inject one.

  • As to that latter point, this can be accomplished using the HAL plugin's injectSelfLink() method:

    $this->plugin('hal')->injectSelfLink($entity, $routeName, $routeIdentifierName);

    This will use the provided route name and route identifier name to create the self relational link.

Alternately, another approach is to use the plugin's createEntity() method. This takes the object you're exposing, plus the route and route identifier names, and returns a ZF\Hal\Entity instance with the self relational link injected:

$entity = $this->plugin('hal')->createEntity($data, $routeName, $routeIdentifierName);

So, now the question is: where should we put this in the manual! :)

@ezimuel
Copy link
Author

ezimuel commented May 30, 2014

I think we can add this information in this recipe https://www.apigility.org/documentation/recipes/hal-from-rpc, what do you think?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment