API平台和带有自定义主体的自定义POST操作

时间:2019-02-19 21:22:18

标签: api symfony swagger openapi api-platform.com

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

我正在使用一个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;

这是控制器:

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),我收到一条错误消息:

  

无法自动装配“ App \ Controller \ SDK \ UserChangePasswordAction()”的参数$ data:它引用类“ App \ Entity \ User”,不存在此类服务

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

注意:我还定义了一个自定义项目操作“ get_active_user”,它可以正常工作。

请我想了解一下:

  • 我做错了什么
  • 它实际上如何工作,

谢谢。

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

  
      
  • “默认值” = {“ _ api_receive” = false},
  •   

现在,控制器将返回一个空的User实体,而不是一个错误。我仍然无法获取提交的数据。

2 个答案:

答案 0 :(得分:0)

那是行不通的,因为那是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;
    }
}

答案 1 :(得分:0)

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

  

“默认值” = {“ _ api_receive” = false},

现在,当我提交数据时,如下图所示: enter image description here

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