-
Notifications
You must be signed in to change notification settings - Fork 118
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Getting current object in relation provider. #290
Comments
Relations in v3.x can not be "dynamically" added or removed, but they can be "dynamically excluded" . This means that your Here an example on how should be done. |
What about building a collection of relations from an array property of the object (e.g. customer->orders). I'm not sure how exclusion strategies would work here?:
|
In that case exclusion strategies will not work in the best way. Here the relation is still one: I know that by HAL specs your case is perfectly valid, but wouldn't in that case be better to use Created #293 as feature request to keep track of it. |
My intention was to create a single relation by following the example given here. To my knowledge it seems the creation of a single relation with multiple links is done by returning an array containing multiple relation objects using the same name. I'm not sure what you are suggesting in this new issue. Are you suggesting to simplify the above process by allowing an array of routes on the relation object? How does this solve the problem of not being able to dynamically build the array of links/routes based on a property of the object? Regarding
|
The problem with the previous way of handling links was that: public function getExtraRelations(Customer $customer) : array
{
foreach ($customer->getOrders() as $order)
{
$relations[] = new Relation(
'orders',
new Route(
'card',
['orderId' => $order->getId()],
true
)
);
}
return $relations;
} When there are multiple order, will return: {
"_links": {
"orders": [
{"href": "/order/1"},
{"href": "/order/2"},
{"href": "/order/3"}
]
}
} But if your object has only one order, will return: {
"_links": {
"orders":
{"href": "/order/1"}
}
} That is wrong as the consumer will expect an array of links, but here gets an object |
Ah, I understand now. So even if I was able to dynamically generate the links, the single object would be quite unexpected. How would you suggest implementing the cards example I gave in the context of the current cababilities of the library while still being valid HAL (without embedding the full objects)? |
IMO the only way (without making changes to the willdurand/Hateoas library) is to return some value-object for your Order object, and define hateoas metadata for that value object. To have: {
"_embedded": {
"orders": [
{"_links":{"href": "/order/1"}},
{"_links":{"href": "/order/3"}},
{"_links":{"href": "/order/3"}}
]
} |
Your value object could be: /** @relation(PUT LINK INFO HERE) */
class ValueOrder
{
function __construct(Order $realOrder){
//...
}
} |
That would work, thanks! |
Sorry to bother you again, but I just ran into the same issue again for another project. I would like to ask why you think passing Previously, using Having to do this is pretty ugly:
compared to:
|
Not passing the
It do not think that is not useful, that is why i have created #293 to keep track of the feature request. I think this is something that can be useful, will be happy to se an implementation proposal. |
My bad, thought that issue was referring to this problem specifically:
But the annotations in my objects also refer to the underlying data. If I want to embed a |
@egonolieux use Hateoas\Configuration\Relation;
use Hateoas\Configuration\Route;
class UserRelPrvider
{
/**
* @return Relation[]
*/
public function getExtraRelations($object, ClassMetadataInterface $classMetadata)
{
// You need to return the relations
$relations = [];
if (!$object->someMethod()) {
$relations[] = new Relation(
'self',
new Route(
'foo_get',
['id' => 'object.getId()']
)
);
}
return $relations;
}
} Without having the actual object that will be used for se, we can not tell anything about the relations that are going to be serialized. Lets consider this second example as it is in 3.x: use Hateoas\Configuration\Relation;
use Hateoas\Configuration\Route;
use Hateoas\Configuration\Exclusion;
class UserRelPrvider
{
private $evaluator;
public function __construct(CompilableExpressionEvaluatorInterface $evaluator)
{
$this->evaluator = $evaluator;
}
/**
* @return Relation[]
*/
public function getExtraRelations(): array
{
// You need to return the relations
return array(
new Relation(
'self',
new Route(
'foo_get',
['id' => $this->evaluator->parse('object.getId()', ['object'])]
),
null,
[],
new Exclusion(
null,
null,
null,
null,
$this->evaluator->parse('object.someMethod()', ['object'])
)
)
);
}
} In this case we do not need the object and we can already call This information as example is used by libraries as NelmioApiDocBundle to automatically generate documentation from the code. In the same way, since the expression-language expressions to generate the links ( Hope this gives you an overview of the difference between evaluating expressions at run-time depending on the underlying data, versus being able to discover the relations at deploy/cache-warm-up time. |
I understand what you mean now, thanks for taking the time to explain! I don't know to what extent you plan on including a replacement for this functionality regarding #293, but what do you think of something like this?
The Maybe we should continue this in the relevant issue #293 ? |
I like your proposal. having a
Actually I do not have plans to work on this feature in the near future, but would be happy to see a PR implementing it, and of course I'm available to review it and/or to provide help. Probably we can continue the conversation on #293 |
In previous version relation providers receives current object as the first argument.
After updating to the latest version I can't find a way to get current object. When I try to pass it with
object
variable like this:then the following error appears:
How can I get current object inside service? I need it because I dynamically add some relations based on current object and authenticated user.
Thanks.
The text was updated successfully, but these errors were encountered: