Giter VIP home page Giter VIP logo

bazingahateoasbundle's People

Contributors

adrienbrault avatar adriensamson avatar ahilles107 avatar christiaan avatar dafish avatar dantleech avatar delboy1978uk avatar goetas avatar guillaumedoury avatar jaimemerino avatar kleiram avatar lyrixx avatar nek- avatar nicksanders avatar nyedidikeke avatar ohartl avatar paxal78 avatar piotrantosik avatar ruudk avatar sydney-o9 avatar takeit avatar thebabayaga avatar w0rma avatar willdurand avatar wouterj avatar xenox avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bazingahateoasbundle's Issues

New Tag for Symfony 6

In the master master/composer.json there is support for symfony 6.

But in the last Release (2.3.0 Latest) from 14 Oct 2021 the composer.json is still fixed on symfony 5.

The same Problem is on https://github.com/willdurand/Hateoas/blob/63e255bb762fd6fa79d973d99ac669daab56c638/composer.json (Latest, Tag: 3.7.0) where the dependency is

"symfony/expression-language": "~3.0 || ~4.0 || ~5.0"

and in the master branch the version is

"symfony/expression-language": "~3.0 || ~4.0 || ~5.0 || ~6.0"

Is there a plan when the new versions should be tagged so that composer can pull them with symfony 6 support?

The Problem with the pipeline is imho that the pulled release from willdurand/Hateoas has not the same symfony/expression-language needs with willdurand/BazingaHateoasBundle in the master branch

Thank you very much!

Xml Configuration

Is possible to specify inside the config file that hateoas use xml for every entity instead of annotation?

Use route names in relations

Hi @willdurand ,

Is it possible to use symfony routes as the href parameter for the relations, instead of using hardcoded URL, as this maks much more sense when using symfony?

Thanks! ๐Ÿ˜„

JMS Serializer 1.0

jms/serializer and jms/serializer-bundle have gone 1.0.
Can we get a compatible release?

PHP8 support

Currently, this bundle can only be installed on PHP 7.2/7.3/7.4.

Support for PHP 8 should be added.

Add cache warmer

It would be really useful to have a cache warmer registered automatically. We've done this manually by adding the following to our services.yaml:

    hateoas.configuration.metadata.cache.cache_warmer:
        class: JMS\SerializerBundle\Cache\CacheWarmer
        arguments:
            $includePaths: ['%kernel.project_dir%/src/Entity']
            $metadataFactory: '@hateoas.configuration.metadata_factory'
        tags: [kernel.cache_warmer]

Unable to use custom URL generator

Hi there,

We're using BazingaHateoasBundle v0.4.0 in Symfony 2.6, and we need to implement our own custom URL generator, however we have come across some issues in using our generator.

We followed the steps to implement one, however the registry reports that it can't find our generator, and that only the "symfony_generator" is available.

The "account_link_generator" url generator is not set. Available url generators are: symfony_generator.

This is the generator class (albeit slimmed-down)

<?php
namespace Sce\AccountDataBundle\Generator;

use Hateoas\UrlGenerator\UrlGeneratorInterface;

class HateoasAccountLinkGenerator implements UrlGeneratorInterface
{
    /**
     * {@inheritdoc}
     */
    public function generate($name, array $parameters, $absolute = false)
    {
        return 'http://service.com/resource/'.$parameters['id'];
    }
}

Here is the service definition:

sce_account_data.generator.hateoas_account_link_generator:
    class: Sce\AccountDataBundle\Generator\HateoasAccountLinkGenerator
    tags:
        - { name: hateoas.url_generator, alias: account_link_generator }

And finally the annotation on the entity:

 * @Hateoas\Relation(
 *      "self",
 *      href = @Hateoas\Route(
 *          name = "sce_account_data.account.get",
 *          parameters = {
 *              "id" = "expr(object.getId())"
 *          },
 *          absolute = true,
 *          generator = "account_link_generator"
 *      )
 * )

I've had a look in URLGeneratorPass.php and added some debug, and from looking at var_dump(array_keys($container->getDefinitions())); that our generator is defined already, and by looking at var_dump($registryDefinition->getMethodCalls()) that it has detected our generator and registered that it should call set on the registry object.

I've also made sure that the bundle is the last loaded bundle in the AppKernel to try and eliminate any other bundles overloading the definitions, however set on the URLGeneratorRegistry just seem to be never called with our generator.

Do you have any idea why this is happening?

Happy to provide further details if required.

Many thanks

Symfony 3 not supported because of security.context

Since Symfony 2.6, the security.context service has been deprecated and split into two new services: security.authorization_checker and security.token_storage.

And now with Symfony 3.0 the security.context service has been totally removed.

I'm using the BazingaHateoasBundle on a profesionnal Symfony 3 project and got stuck because of that.
There is currently a pull request #50 to solve this problem ;)

Symfony 7 support

New major symfony version was released so it'd be great for this bundle to also support it!

Security context for serialization

An issue I run into from time to time is that some links should only be visible when an user has certain permissions. For example, let's say I created a blog API and only admins should be able to delete comments. Something like this could be shown in the _links object like so:

{
    "_links": {
        "delete": {
            "href": "http://example.org/api/posts/14"
        }
    }
}

If I only want this route to be visible for users that have the ROLE_ADMIN role, there's no easy way to do this at the moment besides creating a relation provider that only acts as a sort of proxy for the SecurityContextInterface.

I propose adding something like an granted attribute to the @RelationProvider annotation:

/**
 * @Hateoas\Relation(
 *  "delete",
 *  href = @Hateoas\Route(
 *      "post_delete",
 *      parameters = { "id" = "expr(object.getId())" }
 *  ),
 *  granted={"ROLE_ADMIN"}
 * )
 */
class Post
{
    // properties
}

Is this something that might be worth looking into?

PS: Clearly, this can be labeled as an enhancement.

Ability to configure arbitrary EL variables

WDYT of being able to configure EL variables, that would be a bit like twig global variables:

bazinga_hateoas:
    expression_language:
        context_variables:
            base_rel: https://rels.example.com
            foo: bar

To then be able to:

/**
 * @Hateoas\Relation("expr(base_rel ~ '/users')", ...)
 */

Using SecurityRoles in excludeif...

At present I, as I assume a lot of people have different permission for those that can view compared to those that can view, update, delete. I prefer the idea of stating what is possible early on rather than bouncing people back. Would it be possible to to include an 'is_granted' permission in the exclude if like

/**

  • ...
    *
  • @Hateoas\Relation(
  • "manager",
    
  • href = "expr('/api/users/' ~ object.getManager().getId())",
    
  • embedded = "expr(object.getManager())",
    
  • exclusion = @Hateoas\Exclusion(excludeIf = "!security_context.is_granted([ROLE_SOMETHING])")
    
  • )
    */

Failing tests with Symfony 2.8 and HateoasBundle 1.1.1

Hi

I'm trying to check PHP7 compatibility of the bundles we use in a big project
I saw that travis is failing for php7/symfony2.8 but the failure travis gets is different from the one I'm getting:
In this gist there's the complete test result
https://gist.github.com/marcoalbarelli/f10b6407ce3c230b8b9feb842e5308b9
It seems like the main issue here is how you try to inject mocks, but I didn't have the time to check the actual code.

This is the relevant part of the composer.lock file


            "name": "willdurand/hateoas-bundle",
            "version": "1.1.1",
            "target-dir": "Bazinga/Bundle/HateoasBundle",
            "source": {
                "type": "git",
                "url": "https://github.com/willdurand/BazingaHateoasBundle.git",
                "reference": "a53f6f1d3d8cda3fa8cdd90773cb48e9647a08c5"
            },
            "dist": {
                "type": "zip",
                "url": "https://api.github.com/repos/willdurand/BazingaHateoasBundle/zipball/a53f6f1d3d8cda3fa8cdd90773cb48e9647a08c5",
                "reference": "a53f6f1d3d8cda3fa8cdd90773cb48e9647a08c5",
                "shasum": ""
            },
            "require": {
                "jms/serializer-bundle": "~1.0",
                "symfony/framework-bundle": "~2.2 || ~3.0",
                "willdurand/hateoas": "~2.9"
            },
            "require-dev": {
                "phpunit/phpunit": "~4.5",
                "symfony/expression-language": "~2.4 || ~3.0",
                "twig/twig": "~1.12"
            },
            "type": "symfony-bundle",
            "extra": {
                "branch-alias": {
                    "dev-master": "1.2-dev"
                }
            },
            "autoload": {
                "psr-0": {
                    "Bazinga\\Bundle\\HateoasBundle": ""
                }
            },
            "notification-url": "https://packagist.org/downloads/",
            "license": [
                "MIT"
            ],
            "authors": [
                {
                    "name": "William Durand",
                    "email": "[email protected]"
                }
            ],
            "description": "Integration of Hateoas into Symfony2.",
            "keywords": [
                "HATEOAS",
                "rest"
            ],
            "time": "2016-02-22 13:12:41"
        },

The links are lost when the serialization groups are used

The links are lost when the serialization groups are used :

    /**
     * @FOSRest\View(serializerGroups={"default"})
     */
    public function cgetAction(){

        /** @var Product[] $products */
        $products = $this->get("api_product.product_service")->getAll();

        return $products;
    }

The links are lost due to the ExclusionManager which skip these links, the workaround which works in my projetc is to not skip these relations when exclusion is nullable

// \Hateoas\Serializer\ExclusionManager.php

    private function shouldSkip($object, Exclusion $exclusion = null, SerializationContext $context)
    {
        // Do not skip links when exclusion is null
        if (is_null($exclusion)) {
            return false;
        }

        if (null !== $exclusion
            && null !== $exclusion->getExcludeIf()
            && $this->expressionEvaluator->evaluate($exclusion->getExcludeIf(), $object)
        ) {
            return true;
        }

        if (!$context->getExclusionStrategy()) {
            return false;
        }

        $propertyMetadata = new RelationPropertyMetadata($exclusion);

        return $context->getExclusionStrategy()->shouldSkipProperty($propertyMetadata, $context);
    }

But I do not have enough global understanding to know if it's a good or a bad workaround. Do you have any idea how this problem can be resolved properly ?

Register a new method in expr()

I have an entity with a $filepath property,
And I have a getWebPath() method which gives the relative web path (currently, uploads/some/sub/folders/the-file-name.extension)

But instead of serializing this relative web path :

{
    "id": 1,
    "filepath": "uploads/some/sub/folders/the-file-name.extension"
}

I would prefer to serialize the absolute web one :

{
    "id": 1,
    "filepath": "http://example.com/uploads/some/sub/folders/the-file-name.extension"
}

So I was just wondering, would it be a good practice to register a new method (asset() for instance) inside expr() ?

/**
 * @Hateoas\Relation(
 *      "filepath",
 *      href = "expr(asset(object.getWebPath(), true))"
 * )
 */

Then how to register it in expr() ?

Why the ExtensionDriver is only enabled for annotation driver?


        <service id="hateoas.configuration.metadata.extension_driver" class="%hateoas.configuration.metadata.extension_driver.class%" public="false">
            <argument type="service" id="hateoas.configuration.metadata.annotation_driver" />
        </service>

        <service id="hateoas.configuration.metadata.chain_driver" class="%jms_serializer.metadata.chain_driver.class%" public="false">
            <argument type="collection">
                <argument type="service" id="hateoas.configuration.metadata.yaml_driver" />
                <argument type="service" id="hateoas.configuration.metadata.xml_driver" />
                <argument type="service" id="hateoas.configuration.metadata.extension_driver" />
            </argument>
        </service>

I add a custom configuration extension, it never get executed, I found out that the ExtensionDriver is not enabled for yaml and xml driver, why is it?

[Question] Bundle is using latest Hateoas dev

Hello William,

The document of Hateoas states:

Important: This library is under heavy refactoring. If you are using it, you will find the code in the 1.0 branch. The master branch is a work in progress, and should not be used in production at the moment.

However if I'm not mistaken this Bundle's stable version uses latest of Hateoas?!

So if that is correct, then this Bundle should currently not be used for production stuff right?

Twig extension loading configuration

Bundle provides (undocumented) twig extension. Loading it slow downs TwigService initialization in container (as it initialize heavy guzzle client). We should have option to decide if it should be loaded in application (if we want to use it).

Proposed solution:

  • add option to enable it in configuration (default enable for keeping BC).
  • load it only when config is set to true.

Tell me what do You think about this.

how to use yaml format

Hi,

Instead of using annotations i'd like to use as a configuration file. I've spotted the configuration here https://github.com/willdurand/Hateoas#yaml

Also i've placed a file called hateoas.yml in my bundles config directory but it seems that the bundle isn't autoloading it.

Would you please give me a hint. thanks

500 ERROR

I had this error
{ "code": 500, "message": "The token storage contains no authentication token. One possible reason may be that there is no firewall configured for this URL." }
after using
exclusion = @Hateoas\Exclusion( excludeIf = "expr(is_granted(['ROLE_ADMIN']))" )
Can anyone help me please

Change Symfony2 to Symfony in README.md

Let it read: This bundle integrates Hateoas into Symfony instead of Symfony2 as the project is not only compatible with Symfony2 but all upwards to the current version, Symfony4.

Making it Symfony may encourage potential patronage and usage.

Symfony 7: Service "annotation_reader" is no longer available

I get the following error when using this bundle with symfony 7 and calling bin/console cache:clear:

The service "hateoas.configuration.metadata.annotation_driver" has a dependency on a non-existent service "annotation_reader".

This is because the service "annotation_reader" has been removed in symfony/framework-bundle:7.0.

My project doesn't use the annotations defined in https://github.com/willdurand/Hateoas/tree/master/src/Configuration/Annotation at all.

I was able to work around this issue by defining the service "annotation_reader" in my project manually.

It would be nice if annotations could be make optional in this bundle.

Maybe #104 can help to fix this issue by adding support for native attributes.

Incorrect version required in composer.json

Line 36 of https://github.com/willdurand/BazingaHateoasBundle/blob/master/DependencyInjection/Compiler/ExtensionDriverPass.php results in the following syntax error:

PHP Parse error:  syntax error, unexpected 'class' (T_CLASS), expecting
identifier (T_STRING) or variable (T_VARIABLE) or '{' or '$' in
myapp/vendor/willdurand/hateoas-bundle/Bazinga/Bundle/HateoasBundle/DependencyInjection/Compiler/ExtensionDriverPass.php
on line 36

  [Symfony\Component\Debug\Exception\FatalErrorException]

  Parse Error: syntax error, unexpected 'class' (T_CLASS), expecting
identifier (T_STRING) or variable (T_VARIABLE) or '{' or '$'

PHP 5.4.45-0+deb7u5

Solution is either to correct the required PHP version (5.5 according to php.net) in composer.json, or just provide the interface name as a string.

Symfony service resolver for DIExtraBundle

Hello,

I'm using this bundle for creating an api rest, and also the DIExtraBundle for service annotations.

The issue is that I must declare the service in xml for having a result from the SymfonyContainerResolver class in order of finding my custom relation provider.

I have tested with yml and it doesn't work neither. I've looked into code and I found that the SymfonyContainerResolver class uses the definition in xml for finding the service.

/**
     * {@inheritdoc}
     */
    public function getRelationProvider(RelationProviderConfiguration $configuration, $object)
    {
        if (!preg_match('/^(?P<service>[a-z0-9_.]+):(?P<method>[a-z0-9_]+)$/i', $configuration->getName(), $matches)) {
            return null;
        }

        return array(
            $this->container->get($matches['service']),
            $matches['method']
        );
    }

is it possible of searching the service directly in the service container and not with a regular expression evaluating the xml declaration? That would be great considering the people who use DIExtraBundle or KnpRadBundle for extending annotations.

Thank you

It should provide a way to get a Hateoas instance from the container

This bundle should provide an instance of Hateoas serializer as a service.

It isn't as simple as it seems: a serializer service could have been defined like:

<service id="hateoas.serializer_factory" class="Hateoas\HateoasBuilder" />
<service id="hateoas.serializer"
         class="Hateoas\Hateoas"
         factory-service="hateoas.serializer_factory"
         factory-method="build">
</service>

But this declaration do not take care of the JMSSerializerBundle additions. In fact, this bundle adds some other handlers such as FormErrorHandler to the serializer exposed via the jms_serializer.serializer service.

I think that we need to reuse them, so in fact, we have at least two options:

  • Reuse the HandlerRegistry to add registered handlers on creation in the HateoasBuilder
  • Do not use HateoasBuilder at all but tagged services to add serializer subscribers (and build the link helper needed by Hateoas constructor)

I much prefer the second option but want some feedbacks before making a pull request with changes in this directions.

Release v1.1.2

Could you tag v.1.1.2 to publish the extension driver PR?

Support Custom SerializationContext

Having the ability to use a different serialization context than JMS Serializer would be very beneficial. The use case is when you have an object graph that has the same object represented two different ways. Here is an example, and pardon the length but I feel at least one example would make discussion easier.

You have two objects: Post and User. A Post has a property called "author" which points to a User. Here is some pseudo-ish code for these two classes:

class Post {
    /**
    * @Type("User")
    * @Groups({"posts"})
    */
    var $author;

    /**
    * @Type("string")
    * @Groups({"posts"})
    */
    var $title;

    /**
    * @Type("string")
    * @Groups({"posts"})
    */
    var $content;
}



class User {
    /**
    * @Type("string")
    * @Groups({"users", "posts", "embedded"})
    */
    var $id;

    /**
    * @Type("string")
    * @Groups({"users", "embedded"})
    */
    var $name;

    /**
    * @Type("array")
    * @Groups({"users", "embedded"})
    */
    var $preferences;
}

You have two RESTful routes on your API for this content:

/api/posts/{id}

/api/users/{id}

Say you have the following two objects in your database:

Post:

{
    "id": 1,
    "author": {
        "$ref" : "User",
        "$id" : "1",
        "$db" : "blog"
    },
    "title": "An Example Post",
    "content": "<p>This is a great post.</p>"
}

User:

{
    "id": 1,
    "name": "John Doe",
    "preferences": {
        "lang": "en-US"
    }
},
{
    "id": 2,
    "name": "Jane Doe",
    "preferences": {
        "lang": "en-US"
    }
}

You make a GET to /api/posts/1 and get:

{
    "id": 1,
    "author": {
        "id": 1
    },
    "title": "An Example Post",
    "content": "<p>This is a great post.</p>",
    "_embedded": {
        "author": {
            "id": 1,
            "name": "John Doe",
            "preferences": {
                "lang": "en-US"
            }
        }
    }
}

And, you want to update that Post to be User 2 by sending PUT /api/posts/1:

{
    "id": 1,
    "author": {
        "id": 2
    },
    "title": "An Example Post",
    "content": "<p>This is a great post.</p>"
}

This would work flawlessly if you could pass a SerializationContext to Hateoas Bundle that uses the "embedded" serialization group and separate one to JMS Serializer Bundle that uses the "posts" serialization group. The reason this configuration would be nice is that JMS will silently discard any modified data, but seamlessly update which User the Post references on $author.

As it stands, since Hateoas uses the context from JMS the serialization groups you send apply to all objects in the graph. So, you either exclude the author from the embedded data and force the API user to make a separate request to get the user or use a separate route to handle updating the references, such as: /api/posts/{id}/author.

UrlGeneratorPass incompatible with class parameters

Given a custom url generator defined as a service :

parameters:
    my.url_generator.class:
        Acme\Foo\MyUrlGenerator
services:
    my.url_generator:
        class: %my.url_generator.class%
    tags:
        -
            name: hateoas.url_generator
            alias: my_url_generator

When I compile the container
Then the UrlGeneratorPass fails because it tries to construct a ReflectionClass from the string %my.url_generator.class%.

Over there : https://github.com/willdurand/BazingaHateoasBundle/blob/master/DependencyInjection/Compiler/UrlGeneratorPass.php#L54

I understand that this is used to avoid vendor lock-in and to trim the Symfony UrlGeneratorInterface from superfluous methods. But the check seams plain wrong in this specific case.

How to configure Metadata directories

Question:
In the library's documentation, there is a point Configuring Metadata Locations.
However, I don't understand how to apply that with the bundle: nowhere is mentioned how we have to use the HateoasBuilder in the bundle.

I think by code inspection that, it could be managed with the Metadata/Driver/DriverChain of jms/serializer but I don't understand how.

For example, I want to do the same thing with HateoasBundle than I do here with JMSSerializerBundle:

jms_serializer:
    metadata:
        directories:
            DoctrinePHPCR:
                namespace_prefix: "Doctrine\\ODM\\PHPCR"
                path: "@AppBundle/Resources/config/serializer/DoctrinePHPCR"

Concatenate @Route with expr

Hi. Im trying to give users full route to blog posters. Is there a way to insert homepage route before expr?

/**
 * @Hateoas\Relation(
 *      name = "poster_path",
 *      href = "expr(object.getWebPath())"
 * )
 */

Setting $limitParameterName doesn't impact limit property name

Hello,

When setting $limitParameterName to another value :

public function getMediasAction(ParamFetcher $paramFetcher)
{
    $queryBuilder = $this->getMediaHandler()->all();

    $pagerAdapter = new DoctrineODMMongoDBAdapter($queryBuilder);
    $pager = new Pagerfanta($pagerAdapter);
    $pager->setCurrentPage($paramFetcher->get('page'));
    $pager->setMaxPerPage($paramFetcher->get('hits_per_page'));

    $pagerFactory = new PagerfantaFactory('page', 'hits_per_page');

    return $pagerFactory->createRepresentation(
        $pager,
        new Route('dam_get_medias')
    );
}

Limit property name doesn't change in output :

{
    "page": 1,
    "limit": 2,
    "pages": 214,
    "total": 428,
    "_links": {
        "self": {
            "href": "/app_dev.php/api/medias?page=1&hits_per_page=2"
        },
    },
}

Is this a bug or correct behaviour ?

Best regards

Symfony 5

This bundle does not support symfony 5 yet

Deprectation Notices in Symfony 3.3

I get two deprication messages on the latest version of Symfony

Autowiring services based on the types they implement is deprecated since Symfony 3.3 and won't be supported in version 4.0. You should rename (or alias) the "hateoas.configuration.relations_repository" service to "Hateoas\Configuration\RelationsRepository" instead.

Autowiring services based on the types they implement is deprecated since Symfony 3.3 and won't be supported in version 4.0. You should rename (or alias) the "hateoas.expression.evaluator" service to "Hateoas\Expression\ExpressionEvaluator" instead.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.