我正在设计一个消息传递API,并设置了PUT /message
方法。
有效负载由一个包含三个字段的数组组成:message
,sender
和receiver
- 第一个是消息本身,以下字段分别是用户的表示。有效载荷可以是:
{
"message": "Hi!",
"sender": { "id": 1 },
"receiver": { "id", 2 }
}
通过使用JMSSerializerBundle
,我可以成功地将有效负载转换为Message
实体,并将其用户转换为各自的User
实体。这是Message
实体:
/**
* @ORM\Entity
*/
class Message
{
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\ManyToOne(targetEntity="User")
* @ORM\JoinColumn(name="sender", referencedColumnName="id", nullable=false)
*/
protected $sender;
/**
* @ORM\ManyToOne(targetEntity="User")
* @ORM\JoinColumn(name="receiver", referencedColumnName="id", nullable=false)
*/
protected $receiver;
}
我想要做的是能够接收有效负载,然后将其持久保存在数据库中。不多也不少。控制器如下:
/**
* @Configuration\Method("PUT")
* @Configuration\Route("/message")
*/
public function putMessageAction(Request $request)
{
/** @var Message $message */
$message = $this
->getJMSSerializer()
->deserialize($request->getContent(), 'Message', 'json');
// at this point I want both sender and receiver to be two database users
if ($message->getSender()->getId() === $message->getReceiver()->getId()) {
throw new \Exception("A message's sender and receiver cannot be the same people.");
}
$em = $this->getDoctrine()->getManager();
$em->persist($message);
$em->flush();
return JsonResponse::create([
'message' => 'Message successfully received.'
], 200);
}
我缩写名称空间只是为了关注问题本身。没什么可担心的。 :)
答案 0 :(得分:0)
根据要求,这是一个基于非JMSSerializer的解决方案。未经测试。
// Turn json payload into an array
$data = json_decode($request->getContent(),true);
// Load references to users, no need to load the entire object in
$em = $this->getDoctrine()->getManager();
$sender = $em->getReference('User',$data['sender'];
$receiver = $em->getReference('User',$data['receiver'];
// Build and persist the message
$message = new Message(); // or new Message($sender,$receiver,$data['message']);
$message->setSender($sender);
$message->setReceiver($receiver);
$message->setMessage($data['message']);
$em->persist($message);
$em->flush();
也可以使用表单进行这种映射。
虽然它有点偏离主题,但如果您尝试创建RESTlike接口,那么POST可能是创建新资源的更好解决方案。并且返回201状态代码以及到新资源的重定向链接也更为典型。