Reputation: 147
I'am adding custom POST operation as describe https://api-platform.com/docs/core/operations/#recommended-method
But i each time face an error saying my action doesn't find my entity as service:
"hydra:description": "Cannot autowire argument $user of \"App\Controller\SDK\User\UserCreateAction()\": it references class \"App\Entity\SDK\User\" but no such service exists."
Here is my action:
class UserCreateAction extends BaseAction
{
private $userService;
public function __construct(UserService $userService)
{
$this->userService = $userService;
}
public function __invoke(User $user)
{
return $this->userService->create($user);
}
}
Normally, the action should automatically recognise the $user entity
Upvotes: 4
Views: 4185
Reputation: 147
EDIT (2022/29/11): Please refer to the comment of @Cerad below for the fix.
I realised it's because of my services.yml
.
Actually, among resources which should be available to be used as service, the Entity/
folder was excluded:
App\:
resource: '../src/*'
exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'
So I changed it, I removed the "Entity", and it works fine now:
App\:
resource: '../src/*'
exclude: '../src/{DependencyInjection,Migrations,Tests,Kernel.php}'
Upvotes: 5
Reputation: 18
The solution is not currently in any of the answers here but is posted in a comment.
@cerad explained the right solution
Warning: the __invoke() method parameter MUST be called $data, otherwise, it will not be filled correctly!
Renaming the param to $data
did the job for me.
I could find only one reference though (feel free to add a better one):
https://github.com/api-platform/core/issues/2184
Upvotes: 0
Reputation: 4313
Just like any regular controller, make sure services can be injected :
# symfony/config/services.yaml
App\ApiPlatform\Controller\CreateBookPublication:
tags: ['controller.service_arguments']
and
<?php
// App\ApiPlatform\Controller\CreateBookPublication.php
namespace App\ApiPlatform\Controller;
use App\Entity\Book;
class CreateBookPublication
{
private $bookPublishingHandler;
public function __construct(BookPublishingHandler $bookPublishingHandler)
{
$this->bookPublishingHandler = $bookPublishingHandler;
}
public function __invoke(Book $data): Book
{
$this->bookPublishingHandler->handle($data);
return $data;
}
}
Upvotes: 0
Reputation: 1983
This is very strange case - you are trying to create user that already exists (api platform loads it from your request uri) This is illegal operation. Remove User $user
argument from __invoke
and inject Request
:
class UserCreateAction extends BaseAction
{
private $userService;
public function __construct(UserService $userService)
{
$this->userService = $userService;
}
public function __invoke(Request $request)
{
$userFields = \json_decode($request->getContent(), true);
return $this->userService->create($userFields);
}
}
To understand how it works read about ParamConverter
in symfony. When you trying to inject entity into you controller __invoke method - api platform tries to find entity by {id} in database. This is applicable for item operations.
* itemOperations={
* "custom": {
* "method": "GET",
* "path": "/users/{id}",
Upvotes: 1