我需要使用 PUT 方法实现一个 API,我想在我的 Controller 中使用 ParamConverter 来查找现有实体对象,或者如果实体对象不存在,则创建一个新实体对象。
但是,如果在存储库中找不到实体对象,标准的 Symfony ParamConverter 会返回一个异常。
你有什么想法可以用一种干净整洁的方式做到这一点吗?谢谢。
这是我想做的事情的一个例子(我使用 FOS REST Bundle 来处理 PUT 请求):
/**
* @param Request $request
* @return View
*
* @ParamConverter("video")
*
*/
public function putVideosAction(Request $request, Video $video)
{
try {
return $this->getHandlerVideos()->put($video, $request->request->all());
} catch (InvalidFormException $e) {
return $e->getForm();
}
}
最佳答案
这是一个解决方案。请告诉我您对此的看法。
在你的 Controller 中,我会这样做:
/**
* @param Request $request
* @return View
*
* @Rest\Put()
* @Rest\View()
*
* @ParamConverter("video", converter="app_get_or_create_entity_converter", options={"repository_method" = "findOneById"})
*/
public function putVideosAction(Request $request, Video $video)
{
try {
$video = $this->getHandlerVideos()->put($video, $request->request->all());
return $video;
} catch (InvalidFormException $e) {
return $e->getForm();
}
}
我会这样写一个动态参数转换器:
class GetOrCreateEntityConverter implements \Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter\ParamConverterInterface
{
/**
* @var EntityManagerInterface
*/
protected $entityManager;
/**
* @var ManagerRegistry $registry Manager registry
*/
private $registry;
/**
* @param ManagerRegistry $registry
* @param EntityManagerInterface $entityManager
*/
public function __construct(ManagerRegistry $registry, EntityManagerInterface $entityManager)
{
$this->registry = $registry;
$this->entityManager = $entityManager;
}
public function supports(ParamConverter $configuration)
{
if ('app_get_or_create_entity_converter' !== $configuration->getConverter()) {
return false;
}
return true;
}
/**
* {@inheritdoc}
*
* Applies converting
*
* @throws \InvalidArgumentException When route attributes are missing
* @throws NotFoundHttpException When object not found
*/
public function apply(Request $request, ParamConverter $configuration)
{
$name = $configuration->getName();
$options = $configuration->getOptions();
$class = $configuration->getClass();
$repository = $this->entityManager->getRepository($class);
$repositoryMethod = $options['repository_method'];
if (!is_callable([$repository, $repositoryMethod])) {
throw new \BadMethodCallException($repositoryMethod . ' function does not exist.', 405);
}
$entity = $repository->$repositoryMethod($id);
if (null === $entity) {
$entity = new $class;
}
$request->attributes->set($name, $entity);
}
}
如果你问我为什么在catch中返回一个表单,请去看https://github.com/liuggio/symfony2-rest-api-the-best-2013-way/blob/master/src/Acme/BlogBundle/Controller/PageController.php
关于api - 交响乐 2 : How to use the ParamConverter with a PUT method to get or create an entity object,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38639464/