我在Symfony2中使用FMSRestBundle使用JMSSerializerBundle为实体序列化原型开发了一个REST API。通过GET请求,我可以使用SensioFrameworkExtraBundle的ParamConverter功能根据id请求参数获取实体的实例,并在使用POST请求创建新实体时,我可以使用FOSRestBundle body转换器基于实体创建实体的新实例请求数据。但是当我想更新现有的实体时,使用FOSRestBundle转换器会给出一个没有id的实体(即使id与请求数据一起发送),所以如果我坚持它,它会创建一个新的实体。并且使用SensioFrameworkExtraBundle转换器为我提供没有新数据的原始实体,因此我必须手动从请求中获取数据并调用所有setter方法来更新实体数据。如何使用FOSRestBundle处理REST API中的实体更新(PUT请求)
所以我的问题是,什么是处理这种情况的首选方式?感觉应该有一些方法来处理这个问题,使用请求数据的(反)序列化。我是否缺少与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
而不仅仅是共享一个链接,说明这部分与该链接的代码将有助于OP 。 – GusDeCooL