我正在使用Symfony2和FOSRestBundle以及JMSSerializerBundle构建REST API的原型,用于实体序列化。通过GET请求,我可以使用SensioFrameworkExtraBundle的ParamConverter功能来获取基于id请求参数的实体实例;而使用POST请求创建新实体时,我可以使用FOSRestBundle body converter根据请求数据创建新实体实例。但是,在更新现有实体时,使用FOSRestBundle转换器会得到一个没有id的实体(即使id已经与请求数据一起发送),因此如果我将其持久化,它将创建一个新实体。而使用SensioFrameworkExtraBundle转换器会给我原始实体而不包括新数据,因此我必须手动从请求中获取数据并调用所有setter方法来更新实体数据。
所以我的问题是,如何处理这种情况是首选方式?感觉应该有一些方法可以使用请求数据的(反)序列化来处理这种情况。我是否遗漏了与ParamConverter或JMS序列化器相关的某些内容来处理此情况?我确实意识到有许多方法可以做这种事情,没有一种方法适用于每种用例,只是在寻找适合使用ParamConverter和最少代码编写在控制器/服务中的快速原型设计的东西。
这里有一个控制器示例,其中包括上述的GET和POST操作:
所以我的问题是,如何处理这种情况是首选方式?感觉应该有一些方法可以使用请求数据的(反)序列化来处理这种情况。我是否遗漏了与ParamConverter或JMS序列化器相关的某些内容来处理此情况?我确实意识到有许多方法可以做这种事情,没有一种方法适用于每种用例,只是在寻找适合使用ParamConverter和最少代码编写在控制器/服务中的快速原型设计的东西。
这里有一个控制器示例,其中包括上述的GET和POST操作:
namespace My\ExampleBundle\Controller;
use My\ExampleBundle\Entity\Entity;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Validator\ConstraintViolationListInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use FOS\RestBundle\Controller\Annotations as Rest;
use FOS\RestBundle\View\View;
class EntityController extends Controller
{
/**
* @Route("/{id}", requirements={"id" = "\d+"})
* @ParamConverter("entity", class="MyExampleBundle:Entity")
* @Method("GET")
* @Rest\View()
*/
public function getAction(Entity $entity)
{
return $entity;
}
/**
* @Route("/")
* @ParamConverter("entity", converter="fos_rest.request_body")
* @Method("POST")
* @Rest\View(statusCode=201)
*/
public function createAction(Entity $entity, ConstraintViolationListInterface $validationErrors)
{
// Handle validation errors
if (count($validationErrors) > 0) {
return View::create(
['errors' => $validationErrors],
Response::HTTP_BAD_REQUEST
);
}
return $this->get('my.entity.repository')->save($entity);
}
}
在config.yml文件中,我对FOSRestBundle进行了如下配置:
fos_rest:
param_fetcher_listener: true
body_converter:
enabled: true
validate: true
body_listener:
decoders:
json: fos_rest.decoder.jsontoform
format_listener:
rules:
- { path: ^/api/, priorities: ['json'], prefer_extension: false }
- { path: ^/, priorities: ['html'], prefer_extension: false }
view:
view_response_listener: force