【发布时间】:2014-03-31 07:29:23
【问题描述】:
我正在使用 JMSSerializerBundle 使用 FOSRestBundle 在 Symfony2 中对 REST API 进行原型设计,以进行实体序列化。通过 GET 请求,我可以使用 SensioFrameworkExtraBundle 的 ParamConverter 功能根据 id 请求参数获取实体的实例,并且在使用 POST 请求创建新实体时,我可以使用 FOSRestBundle 正文转换器基于请求数据。但是当我想更新现有实体时,使用 FOSRestBundle 转换器会给出一个没有 id 的实体(即使 id 是与请求数据一起发送的),所以如果我坚持它,它将创建一个新实体。并且使用 SensioFrameworkExtraBundle 转换器为我提供了没有新数据的原始实体,因此我必须手动从请求中获取数据并调用所有 setter 方法来更新实体数据。
所以我的问题是,处理这种情况的首选方法是什么?感觉应该有某种方法可以使用请求数据的(反)序列化来处理这个问题。我是否遗漏了与处理这种情况的 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
【问题讨论】:
标签: rest symfony fosrestbundle jmsserializerbundle