You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Custom Operations: Action-Domain-Responder with Symfony4 doesn't seem to find Action #537
I was trying to create a custom operations following this docs and when i go to /api then it says that book_special route is unknown.
If i do the same thing but with a controller, then it works.
Here is my code for ADR pattern:
Entity Book:
namespace App\Entity\Library;
use ApiPlatform\Core\Annotation\ApiProperty;
use ApiPlatform\Core\Annotation\ApiResource;
use ApiPlatform\Core\Annotation\ApiSubresource;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ApiResource(
* iri="http://bib.schema.org/ComicStory",
* attributes={"access_control"="is_granted('ROLE_USER')"},
* itemOperations={
* "get"={"method"="GET"},
* "special"={"route_name"="book_special"}
* }
* )
* @ORM\Entity
*/
class Book
{
...
And the Action:
<?php
namespace App\Action;
use App\Entity\Book;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Symfony\Component\Routing\Annotation\Route;
/**
* @todo Doesn't seem to be catched by Api-Platform
*
* Class BookSpecial
* @package App\Action
*/
class BookSpecial
{
public function __construct()
{
}
/**
* @Route(
* name="book_special",
* path="/books/{id}/special",
* defaults={"_api_resource_class"=Book::class, "_api_item_operation_name"="special"}
* )
* @Method("GET")
*/
public function __invoke($data) // API Platform retrieves the PHP entity using the data provider then (for POST and
// PUT method) deserializes user data in it. Then passes it to the action. Here $data
// is an instance of Book having the given ID. By convention, the action's parameter
// must be called $data.
{
return $data; // API Platform will automatically validate, persist (if you use Doctrine) and serialize an entity
// for you. If you prefer to do it yourself, return an instance of Symfony\Component\HttpFoundation\Response
}
}
And with the same entity, here is the controller that make all works:
<?php
namespace App\Controller\Api;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use \Symfony\Component\HttpFoundation\JsonResponse;
class Book extends Controller
{
/**
* @Route("/api/books/{id}/special", name="book_special", requirements={"id": "\d*"})
* @Method({"GET"})
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function specialAction($id)
{
return JsonResponse(['it works' => 'yes', ]);
}
}
When i read the docs, i see that ApiPlatform does introspection and look for src/AppBundle/Action/* classes. But in Sf3+ (i'm running on 4) my Action is in src/Action , so i expected the framework to be unable to find the Action.
# services.yamlservices:
_defaults:
autoconfigure: trueautowire: truepublic: falseApp\Controller\:
resource: './src/App/Controller/*'# this path may be different obviouslytags: ['controller.service_arguments']
Might need to be loaded in config/routes/annotations:
Ok i'll test it tomorrow.
Is it in the documentation, i don't see anythong about this in https://api-platform.com/docs/core/operations ?
If you need i may do a PR on the docs project.
No, I've just worked it out as I was also having the same issue. Problem with the docs is they are predominantly targeted at PRE-Flex Symfony, so not as simple as just adding the above to the docs.
By this I mean there is a lot of mention of AppBundle/ which no longer exists.
Hi,
It work fine, but this custom operation return the entity collection/item operations already filtered.
How to make a top ten book for example, instead of return the complete $data ,
thanks
Cool @BonnieDoug i've tested it and it works well.
Not sure i'm telling the truth (and i would like to know how to do this in a correct way), but maybe you could inject the the service like EntityManagerInterface
and then in your method do the query you want and return a JsonResponse built by yourself. Maybe a better way would be to build a serializer instead of using the JsonResponse but wthat would be valuable only if you re-use this serializer.
Activity
soyuka commentedon Jan 24, 2018
I think that what you did should work
Service declaration
Might need to be loaded in
config/routes/annotations:Controller using the "Action" pattern
Yes I declare my route on the class because the controller is handling only one route.
Link to Api Platform
If you want the api platform listeners to handle the route:
DougHayward commentedon Jan 29, 2018
To fix the issue you simply need to add the Action directory to the service loader:
And then add the Action folder to your annotations loader:
Rebolon commentedon Jan 29, 2018
Ok i'll test it tomorrow.
Is it in the documentation, i don't see anythong about this in https://api-platform.com/docs/core/operations ?
If you need i may do a PR on the docs project.
DougHayward commentedon Jan 29, 2018
No, I've just worked it out as I was also having the same issue. Problem with the docs is they are predominantly targeted at PRE-Flex Symfony, so not as simple as just adding the above to the docs.
By this I mean there is a lot of mention of
AppBundle/which no longer exists.Rebolon commentedon Jan 29, 2018
alifs-dev commentedon Feb 1, 2018
Hi,
It work fine, but this custom operation return the entity collection/item operations already filtered.
How to make a top ten book for example, instead of return the complete $data ,
thanks
Rebolon commentedon Feb 2, 2018
Cool @BonnieDoug i've tested it and it works well.
Not sure i'm telling the truth (and i would like to know how to do this in a correct way), but maybe you could inject the the service like EntityManagerInterface
and then in your method do the query you want and return a JsonResponse built by yourself. Maybe a better way would be to build a serializer instead of using the JsonResponse but wthat would be valuable only if you re-use this serializer.