Sil
Sil

Reputation: 1330

ApiPlatform/Symfony - Generate path for resources

I like to generate the uri for an APiPlatform resource, which seems pretty elementary to me, but I can't seem to find out how. This is what I'd like to accomplish:

Given the resource definition below I'd like get the url based on the resource class name, operation type and operation name.

/**
 * @ApiResource(
 *     itemOperations={"GET"},
 *     collectionOperations={"GET"}
 * )
 */
class Customer
{
    // ... 
}
$path = $someApiPlatformService->getOperationPath(Customer::class, ApiPlatform\Core\Api\OperationType::COLLECTION, 'GET');

Expected value of path would be /api/customers.

$itemId = 'someid';
$path = $someApiPlatformService->getOperationPath(Customer::class, ApiPlatform\Core\Api\OperationType::ITEM, 'GET', $itemId);

Expected value of path would be /api/customers/someid.

Upvotes: 2

Views: 2450

Answers (2)

Daniil Yaroshuk
Daniil Yaroshuk

Reputation: 11

In api-platform/core:3.1:

class UrlGenerator
{
    public function __construct(
        private readonly ResourceMetadataCollectionFactoryInterface $resourceMetadataCollectionFactory,
        private readonly RouterInterface $router,
    ) {
    }

    public function getAllUrlsForResource(string $resourceClass): array
    {
        $urls = [];

        foreach ($this->resourceMetadataCollectionFactory->create($resourceClass) as $resourceMetadata) {
            foreach ($resourceMetadata->getOperations() as $operation) {
                $urls[] = $this->router->getRouteCollection()->get($operation->getName())->getPath();
            }
        }

        return $urls;
    }
}

Upvotes: 1

rugolinifr
rugolinifr

Reputation: 1281

ABOUT URL GENERATION

Your problem is mostly handled by the IriConverterInterface::getIriFromResourceClass() method. This is api-platform core service to convert URLs to entities and entities to URLs.

Howewer, it does not use the operation name because as explained here :

By default, API Platform uses the first GET operation defined in itemOperations to generate the IRI of an item and the first GET operation defined in collectionOperations to generate the IRI of a collection

PARTIAL SOLUTION

Since IriConverterInterface is not enough, you need to

  1. calculate your route name, for example with the internal (i.e forbidden, i don't know what service to use for now, but I guess it is an interface within the Routing namespace) RouteNameGenerator::generate(),
  2. then pass it to the UrlGeneratorInterface::generate() method, as explained by Symfony here
$resourceNameAsArray = explode('\\', Customer::class);
$resourceShortName = $resourceNameAsArray[count($resourceNameAsArray) -1];
$routeName = ApiPlatform\Core\Bridge\Symfony\Routing\RouteNameGenerator::generate('GET', $resourceShortName, ApiPlatform\Core\Api\OperationType::COLLECTION);
$path = $urlGenerator->generate($routeName);

Upvotes: 4

Related Questions