2014-10-01 53 views
0

我正在设计一个消息传递API,并且已经设置了一个PUT /message方法。如何检索实体的相关实体?

有效载荷由包含三个字段的数组组成:messagesenderreceiver - 第一个是消息本身,下面的字段都是用户的表示。有效载荷可以是这样的:

{ 
    "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

我们可以假设它不起作用吗?您是否配置了JMSSerializerBundle实际从数据库中提取现有的发送者/接收者实体? – Cerad 2014-10-01 13:34:03

+0

@Cerad是的,它不工作。当我收到一条消息时,接收者和发送者都是空的,所以我不能马上坚持消息。我不知道该如何为JMSSerializer提供相关实体。你有什么提示吗? – rodrigorigotti 2014-10-01 13:40:32

+0

如果需要,我可以告诉你如何在没有JMSSerializer的情况下执行此操作。我发现这些软件包有点过于设计和混乱,所以我停止使用它。否则,请深入文档或等待熟悉该软件包的人员停下来。 – Cerad 2014-10-01 13:44:04

回答

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(); 

也可以使用这种形式进行映射。

尽管它有点偏离主题,但如果您尝试创建一个类似REST的界面,那么POST可能是创建新资源的更好解决方案。并且将201状态码连同重定向链接一起返回到新资源也更典型。

+0

通过告诉'POST'是正确的方法是正确的,但不是因为我正在创建资源,而是因为它是一种非幂等方法。每次发布消息都会改变我的数据库状态。我会尝试这个实现。 :) – rodrigorigotti 2014-10-01 14:14:03