Reputation: 147
I hope I'm right to ask this. I've looked at (almost) all similar concern but I ain't satisfied yet.
I'm working on a User entity and for days (weeks actually) now i'm trying to POST a user with a custom body. Here's some part of my entity User :
/**
* @ApiResource(
* normalizationContext={"groups"={"read"}},
* denormalizationContext={"groups"={"write"}},
* itemOperations={
* "get",
* "put",
* "delete",
* "get_active_user"={
* "method"="GET",
* "path"="/users/active/me",
* "controller"=UserReadAction::class,
* "defaults"={"_api_receive"=false},
* "swagger_context"={
* "parameters"={
*
* }
* }
* },
* },
* collectionOperations={
* "change_password"={
* "method"="POST",
* "path"="/users/active/changepassword",
* "controller"=UserChangePasswordAction::class,
* "normalization_context"={"groups"={"afup"}},
* "defaults"={"_api_receive"=false},
* "swagger_context"={
* "summary" = "Change user password",
* "parameters"={
* {
* "name" = "User",
* "in" = "body",
* "schema" = {
* "type" = "object",
* "properties" = {
* "password" = {"type"="string"},
* "nom" = {"type"="string"},
* }
* },
* "required" = "true",
* }
* },
* }
* }
* }
* )
* @ORM\Entity(repositoryClass="App\Repository\UserRepository")
* @ORM\Table(name="users")
*/
class User implements UserInterface
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
* @Groups({"read", "write", "afup"})
*/
private $id;
Here is the controller:
namespace App\Controller\SDK;
use App\Entity\User;
use App\Service\SDK\UserService;
use Symfony\Component\Security\Core\Security;
class UserChangePasswordAction
{
public function __invoke(User $data)
{
var_dump($data);die;
}
}
And the services.yaml (some part) file
services:
# default configuration for services in *this* file
_defaults:
autowire: true # Automatically injects dependencies in your services.
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
public: false # Allows optimizing the container by removing unused services; this also means
# fetching services directly from the container via $container->get() won't work.
# The best practice is to be explicit about your dependencies anyway.
# makes classes in src/ available to be used as services
# this creates a service per class whose id is the fully-qualified class name
App\:
resource: '../src/*'
exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'
# controllers are imported separately to make sure services can be injected
# as action arguments even if you don't extend any base controller class
App\Controller\:
resource: '../src/Controller/*'
tags: ['controller.service_arguments']
When I try this (see var_dump in controller), i get an error saying:
Cannot autowire argument $data of "App\Controller\SDK\UserChangePasswordAction()": it references class "App\Entity\User" no such service exists
I read the official doc and it seems that the _invoke method should automatically retrieve the entity. But it does not work for me.
Notice: I also defined a custom item operation "get_active_user" and it works fine.
Please I would like to understand :
Thank you.
EDIT: In the collectionOperation definition, i removed the following setting which means that we manually want to handle data (User) retrieval :
- "defaults"={"_api_receive"=false},
Now, the controller returns an empty User entity, not an error. I still can't get the submitted data.
Upvotes: 2
Views: 13361
Reputation: 1057
It is not working because that is a CollectionOperation
. In this case, you can get the user through TokenStorageInterface
namespace App\Controller\SDK;
use App\Entity\User;
use App\Service\SDK\UserService;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
class UserChangePasswordAction
{
private $tokenStorage;
public function __construct(TokenStorageInterface $tokenStorage)
{
$this->tokenStorage = $tokenStorage;
}
public function __invoke(Request $request) //Get request if you want o keep args empty
{
var_dump($this->tokenStorage->getToken()->getUser());die;
}
}
Upvotes: 0
Reputation: 147
The edit of my question fix the concern. Actually, I just needed to remove this annotation from the POST opration definition :')
"defaults"={"_api_receive"=false},
Now, when I submit the data, I get them as on the following image :
This annotation is important when you write custom GET operation.
Upvotes: 1