Skip to content

Latest commit

 

History

History
287 lines (220 loc) · 6.32 KB

index.md

File metadata and controls

287 lines (220 loc) · 6.32 KB

BazingaHateoasBundle

This bundle integrates Hateoas into Symfony.

Installation

Step 1: Download the Bundle

Open a command console, enter your project directory and execute the following command to download the latest stable version of this bundle:

$ composer require willdurand/hateoas-bundle

This command requires you to have Composer installed globally, as explained in the installation chapter of the Composer documentation.

Step 2: Enable the Bundle

Note: this step is not required if you are using Symfony Flex

Then, enable the bundle by adding the following line in the app/AppKernel.php file of your project:

<?php
// app/AppKernel.php

// ...
class AppKernel extends Kernel
{
    public function registerBundles()
    {
        $bundles = array(
            // ...
            new Bazinga\Bundle\HateoasBundle\BazingaHateoasBundle(),
        );
        
        // ...
    }
}

Note: The bundle requires the JMSSerializerBundle to be registered. If you haven't done that already, you should register it in the kernel aswell:

// app/AppKernel.php

// ...
public function registerBundles()
{
    $bundles = array(
        // ...
        new JMS\SerializerBundle\JMSSerializerBundle(),
    );

    // ...
}

Usage

Mapping Objects

Refer to the Hateoas documentation to find out how to map your objects.

Serializing objects

The BazingaHateoasBundle transparently hooks into the JMS serializer, there are no special considerations:

// My/Controller.php

class SomeController extends Controller
{
    public function resourceAction(Request $request)
    {
        $post = $repository->find('BlogBundle:post');
        $json = $this->container->get('jms_serializer')->serialize($post, 'json');

        return new Response($json, 200, array('Content-Type' => 'application/json'));
    }
}

An example using dependency injection:

// My/Controller.php

use JMS\Serializer\SerializerInterface; 

class SomeController extends Controller
{
    private $serializer;
    
    public function __consttruct(SerializerInterface $serializer)
    {
        $this->serializer = $serializer;
    }
    
    public function resourceAction(Request $request)
    {
        $post = $repository->find('BlogBundle:post');
        $json = $this->serializer->serialize($post, 'json');

        return new Response($json, 200, array('Content-Type' => 'application/json'));
    }
}

Expression Language

This bundle provides three extra functions to the expression language:

is_granted

Allows you to exclude certain routes by checking whether the currently authenticated user has certain permissions or not. For example:

use Hateoas\Configuration\Annotation as Hateoas;

/**
 * @Hateoas\Relation(
 *      "delete",
 *      href = @Hateoas\Route(
 *          "post_delete",
 *          parameters = { "id" = "expr(object.getId())" }
 *      ),
 *      exclusion = @Hateoas\Exclusion(
 *          excludeIf = "expr(not is_granted('ROLE_ADMIN'))"
 *      )
 * )
 */
class Post
{
    // ...
}

If the authenticated user has the ROLE_ADMIN role the route will be exposed, otherwise the route will be excluded.

parameter

Allows you to fetch a parameter from the service container:

/**
 * @Hateoas\Relation(
 *      "delete",
 *      href = @Hateoas\Route(
 *          "post_delete",
 *          parameters = { "foo" = "expr(parameter('foo'))" }
 *      )
 * )
 */
class Post
{
    // ...
}

service

Allows you to fetch a service from the service container.

Extending

RelationProvider

A relation provider provide relations (links) for a given class.

You can add new relation providers by implementing the Hateoas\Configuration\Provider\RelationProviderInterface interface and adding a definition to the dependency injection configuration with the tag hateoas.relation_provider:

<?xml version="1.0" ?>
<container ...>

    <!-- ... -->

    <services>
        <!-- ... -->

        <service id="acme_foo.hateoas.relation_provider.foobar" class="Acme\FooBundle\Hateoas\RelationProvider\Foobar">
            <tag name="hateoas.relation_provider" />
        </service>
    </services>
</container>

Configuration Extension

A configuration extension allows you to override already configured relations.

You can add an extension configuration by adding a definition to the dependency injection configuration with the tag hateoas.configuration_extension:

<?xml version="1.0" ?>
<container ...>

    <!-- ... -->

    <services>
        <!-- ... -->

        <service id="acme_foo.hateoas.configuration_extension.foobar" class="Acme\FooBundle\Hateoas\ConfigurationExtension\AcmeFooConfigurationExtension">
            <tag name="hateoas.configuration_extension" />
        </service>
    </services>
</container>
<?php
namespace Acme\FooBundle\Hateoas\ConfigurationExtension;

use Hateoas\Configuration\Metadata\ConfigurationExtensionInterface;
use Hateoas\Configuration\Metadata\ClassMetadataInterface;
use Hateoas\Configuration\Relation;

class AcmeFooConfigurationExtension implements ConfigurationExtensionInterface
{
    /**
     * {@inheritDoc}
     */
    public function decorate(ClassMetadataInterface $classMetadata)
    {
        if (0 === strpos('Acme\Foo\Model', $classMetadata->getName())) {
            // Add a "root" relation to all classes in the `Acme\Foo\Model` namespace
            $classMetadata->addRelation(
                new Relation(
                    'root',
                    '/'
                )
            );
        }
    }
}

Reference Configuration

# app/config/config*.yml

bazinga_hateoas:
    metadata:
        cache:                file
        file_cache:
            dir:              '%kernel.cache_dir%/hateoas'
    serializer:
        json: hateoas.serializer.json_hal
        xml: hateoas.serializer.xml
    twig_extension:
        enabled: true

Testing

Setup the test suite using Composer:

$ composer install --dev

Run it using PHPUnit:

$ phpunit