core
core copied to clipboard
[v3][UuidUriVariableTransformer] Harden the supports method of the Uuid transformer
Description
I have a resource in API Platform v2 called routes
and I have it setup so that I can call
/routes/[uuid_here]
or routes/[path_here]
where uuid would be a regular UUID but I also wanted to use paths such as /contact
resulting in a full resource path /routes//contact
Before I could just do this, set my ID URI variable requirements and then handle everything in a custom data provider. So I have created the same as a new Sate Provider and it is here where I would use the string which may be a path or UUID to first lookup the resource by Path, before creating a UUID from the string if that failed to find a result and then lookup the result again.
If the supportsTransformation
method detected whether the string was an actual UUID first then I could get past this.
Additionally, if there was a way to configure not to use the data transformer on a per route level, then perhaps I could disable this transformer...
For now I think I may have to decorate the transformer to disable it perhaps when I am not using a UUID..
Any thoughts on a better approach for me to get the result I'm after in v3 - or perhaps just a better practice/approach.
TIA.
For my needs I've currently just decorated like this
<?php
declare(strict_types=1);
namespace Silverback\ApiComponentsBundle\RamseyUuid\UuidUriVariableTransformer;
use ApiPlatform\Api\UriVariableTransformerInterface;
use ApiPlatform\Exception\InvalidUriVariableException;
use ApiPlatform\RamseyUuid\UriVariableTransformer\UuidUriVariableTransformer as BaseUuidUriVariableTransformer;
/**
* @author Daniel West <[email protected]>
*/
class UuidUriVariableTransformer implements UriVariableTransformerInterface
{
private BaseUuidUriVariableTransformer $decorated;
public function __construct(BaseUuidUriVariableTransformer $decorated)
{
$this->decorated = $decorated;
}
public function transform($value, array $types, array $context = [])
{
try {
return $this->decorated->transform($value, $types, $context);
} catch (InvalidUriVariableException $exception) {
return $value;
}
}
public function supportsTransformation($value, array $types, array $context = []): bool
{
return $this->decorated->supportsTransformation($value, $types, $context);
}
}
Perhaps we could work out a context where we could fallback to the original value if the UUID fails?
I feel this is way too specific for us to add a condition to return the original value if the uuid fails no?
Possibly, I've just decorated it in my bundle for now, but I wonder if a dev may want to be able to use an identifier or another field, and if they do, they'll come across this error. I suppose the question is, if the ID isn't a UUID, is the best course of action to continue trying or to fail and throw the exception. If we failover I think we'd get a 404 instead of a server error.
(I think it was throwing a server error, I'd have to double check)
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.