Symfony - 从控制器返回命令类的 json 输出

问题描述

在我的 Symfony 项目中,我创建了一个命令类来删除特定用户

我在 Command 类构造函数中注入了必需的参数“email”。

我从未尝试过在控制器中实现命令,所以我在那里遇到了问题。

我想在控制器中触发 API 调用,如果命令成功,它将返回所需的 json 输出

我怎样才能做到这一点?

我的命令类:

protected static $defaultName = 'user:delete';

$entityManager;
private $userService;
private $email;

public function __construct(string $email = null,EntityManagerInterface $entityManager,KeycloakApi $keycloakApi)
{
    parent::__construct($email);

    $this->entityManager = $entityManager;
    $this->userService = $userService;
}

protected function configure()
{
    $this
        ->setDescription('Deletion of selected user.')
        ->addArgument('email',InputArgument::required,'User email');
}

protected function execute(InputInterface $input,OutputInterface $output)
{
    $user = $this->userService->getUserByEmail($this->email);
    if (empty($user)) {
        throw new Exception('USER_DOESNT_EXIST');
    }

    $this->userService->deleteUser($user['id']);
    $output->writeln('Done!');
}

我尝试在控制器中得到我想要的:

/**
 * @Route("/delete/test",name="delete_test")
 */
public function testDelete(): JsonResponse
{

    $application = new Application($this->kernel);
    $application->setAutoExit(false);

    $input = new ArrayInput(array("user:delete"));
    $output = new BufferedOutput();
    // Run the command
    $retval = $application->run($input,$output);

    dump($retval);die;
}

主要问题是如何在需要为此端点提供的命令中传递电子邮件参数?

解决方法

正如评论所说,您不应该从控制器调用命令,两者都是应用程序的不同入口点。控制器用于从网络访问和从cli执行的命令。

您不应将域逻辑放在这两个文件中。

这是一个可能的例子:

控制器:

/**
 * @Route("/delete/{email}",name="delete")
 */
public function delete(string $email,DeleteUserHandler $handler): JsonResponse
{
    $handler->handle($email);

    return new JsonReponse(null,204);
}

删除用户处理程序:

...
public function handle(string $email): void
{
    $user = $this->userService->getUserByEmail($this->email);
    if (empty($user)) {
        throw new Exception('USER_DOESNT_EXIST');
    }

    $this->userService->deleteUser($user['id']);
}

我保留了一些你的代码,但在删除之前你甚至不需要找到 IMO(只是可能添加一个安全性以避免任何人删除任何人)

使用这种代码,如果需要,您可以在命令(或任何地方)中重用“DeleteUserHandler”,并且真正删除用户的代码不再与入口点耦合