API 平台和自定义 POST 使用自定义主体的操作

API Platform and custom POST operation with custom body

我希望我问的是对的。我看过(几乎)所有类似的问题,但我还不满意。

我正在研究一个用户实体,几天(实际上是几周)现在我正在尝试 POST 一个具有自定义主体的用户。这是我的实体用户的一部分:

/**
 * @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;

这是控制器:

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;
    }
}

和 services.yaml(部分)文件

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']

当我尝试此操作时(请参阅控制器中的 var_dump),我收到一条错误消息:

Cannot autowire argument $data of "App\Controller\SDK\UserChangePasswordAction()": it references class "App\Entity\User" no such service exists

我看了官方文档,_invoke 方法似乎应该自动检索实体。但这对我不起作用。

注意:我还定义了一个自定义项目操作"get_active_user"并且它工作正常。

请多多谅解:

谢谢。

编辑: 在 collectionOperation 定义中,我删除了以下设置,这意味着我们要手动处理数据(用户)检索:

  • "defaults"={"_api_receive"=false},

现在,控制器 returns 一个空的用户实体,不是错误。我仍然无法获取提交的数据。

它不起作用,因为那是 CollectionOperation。这种情况下,可以通过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;
    }
}

我的问题的编辑解决了这个问题。实际上,我只需要从 POST 操作定义中删除此注释 :')

"defaults"={"_api_receive"=false},

现在,当我提交数据时,我得到的数据如下图所示:

当您编写自定义 GET 操作时,此注释很重要。