【问题标题】:Symfony -Return json output of Command Class from ControllerSymfony - 从控制器返回命令类的 json 输出
【发布时间】:2021-01-26 12:52:22
【问题描述】:

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

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

我从来没有尝试在控制器中实现命令,所以我有问题。

我想在 Controller 中触发 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;
}

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

【问题讨论】:

  • 你为什么不直接从你的控制器调用userService?这是一种避免在控制器中调用命令的做法,因为您正在混合使用 cli 和 web contecxt。它也损害了表演而没有收获
  • 会有三种删除方式,这是第一种。所以一个 api 调用将同时处理所有三个。所有三个都将输入到命令类中。 @麦斯基
  • 这是一个非常糟糕的主意。如果您想隔离逻辑以供重用,请将其移至 HTTP 控制器和控制台命令都使用的另一层。

标签: php api symfony command symfony4


【解决方案1】:

正如 cmets 所说,您不应该从控制器调用命令,两者都是应用程序的不同入口点。控制器用于从 web 访问和从 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”,并且真正删除用户的代码不再与入口点耦合

【讨论】:

    猜你喜欢
    • 2015-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多