feat(symfony): add `getOperation` Expression Language function on Mercure topics
| Q | A |
|---|---|
| Branch? | 3.3 |
| Tickets | N/A |
| License | MIT |
| Doc PR | TODO |
Description
When using Mercure on a resource, it's possible to specify multiple topics using Symfony Expression Language:
#[ApiResource(
mercure: [
'topics' => [
'@=iri(object)',
'@=iri(object.getOwner()) ~ "/?topic=" ~ escape(iri(object))',
'@=iri(object, '.UrlGeneratorInterface::ABS_PATH.')', // you can also change the reference type
'https://example.com/books/1',
],
],
)]
(source: https://api-platform.com/docs/core/mercure/#dispatching-restrictive-updates-security-mode)
But the iri Expression Language function does not allow to send the second argument of IriConverter::getIriFromResource ($operation), which will just retrieve the first Get operation detected on the resource. While using multiple operations, it should be possible to specify which operation to use to generate the IRI.
Proposition
Considering the following resource with multiple operations:
#[ApiResource(
operations: [
new Get(uriTemplate: '/foos/{id}{._format}'),
new Get(uriTemplate: '/foos/bars/{id}{._format}'),
new Post(uriTemplate: '/foos{._format}'),
]
)]
On POST /foos request, I want to send a Mercure Update to both Get operations identified by their uriTemplate.
Introducing getOperation Expression Language function (currently only) available on Mercure topics feature:
#[ApiResource(
// ...
mercure: [
'topics' => [
'@=iri(object)',
'@=iri(object, '.UrlGeneratorInterface::ABS_URL.', getOperation(object, "/foos/bars/{id}{._format}"))'
],
]
)]
Note: the
objectvariable is required asgetOperationfirst argument to retrieve the resource class. It's also possible to refer to a class name directly (e.g.: using DTO):
'@=iri(object, '.UrlGeneratorInterface::ABS_URL.', getOperation('.OutputDto::class.', "/a/custom/dtos/{id}{._format}"))'
@soyuka is it ok to merge this one too?