我是Symfony的新手,并且在实现RESTful API时遇到了问题,特别是传入的JSON不包含所有参数的表单 .
到目前为止,我设置了一个处理POST请求的控制器 . 应用程序POST一个包含 isPaired
和/或 isTutorialSeen
字段的JSON .
- 案例1(工作案例):
当POST查询包含 {"isTutorialSeen":true, "isPaired": true}
时,当我尝试 $form->get('isPaired')->getData()
或 $form->get('isTutorialSeen')->getData()
时,这两个字段都设置为true . 这就是我的期望 .
- 案例2(非工作案例):
当POST查询包含 {"isTutorialSeen":true}
时,我可以看到当我尝试 $form->get('isPaired')->getData()
时,表单的isPaired字段设置为false . 可能是因为该字段未在JSON中传递 . 不在JSON中传递它应该具有"don't update it"的含义,而不是"set it to false" . 与HTTP 'PATCH'语法相同 .
我正在抓挠我的头发试图弄清楚我怎么能得到一个'null',而不是一个'假'回来 .
我的控制器实现如下:
/**
* @Rest\Post("/installation/state")
*
*/
public function installationStateAction(Request $request, Subscription $subscription)
{
$view = null;
$form = $this->createForm(InstallationStateType::class);
ControllerUtils::handleForm($request, $form);
if ($form->isValid()) {
$isPaired = $form->get('isPaired')->getData();
$isTutorialSeen = $form->get('isTutorialSeen')->getData();
if ($isPaired !== null)
$subscription->setIsPaired($isPaired);
if ($isTutorialSeen !== null)
$subscription->setIsTutorialSeen($isTutorialSeen);
$this->getDoctrine()->getManager()->flush($subscription);
}
$view = $this->view($subscription, Codes::HTTP_OK);
return $this->handleView($view);
}
InstallationStateType如下:
/**
* Form for InstallationState.
*/
class InstallationStateType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('isTutorialSeen', CheckboxType::class, ['required' => false]);
$builder->add('isPaired', CheckboxType::class, ['required' => false]);
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$defaultsOptions = [
'data_class' => null
];
$resolver->setDefaults($defaultsOptions);
}
public function getName()
{
return 'installationstate';
}
}
订阅实体字段是:
/**
* @ORM\Column(type="boolean", name="is_paired", options={"default"=FALSE})
*
* @JSON\Expose
* @JSON\Groups({"api_process"})
* @JSON\Since("1.0")
* @JSON\SerializedName("isPaired")
*
* @var boolean
*/
protected $isPaired;
/**
* @ORM\Column(type="boolean", name="is_tutorial_seen", options={"default"=FALSE})
*
* @JSON\Expose
* @JSON\Groups({"api_process"})
* @JSON\Since("1.0")
* @JSON\SerializedName("isTutorialSeen")
*
* @var boolean
*/
protected $isTutorialSeen;
也许实体配置中的options = {“default”= FALSE}对此负责,但是在持久层中将false作为默认值是有意义的,在负责映射表单数据的层中将其强制为false (或缺少数据)对象不是我需要的 . 任何帮助将不胜感激 !
2 回答
实体的默认字段值设置如下:
但我不确定在这种情况下是否会有所帮助 .
当您要创建一个全新的资源时,您使用POST方法 . 根据设计,POST请求方法请求Web服务器接受并存储请求消息正文中包含的数据 .
如果您决定更新资源,则应创建PUT或PATCH请求 . PATCH主要就像PUT一样,除了你不需要发送整个资源体 .
所以,你必须改变的第一件事是 - 使用PUT(或PATCH)进行更新 .
如果您要使用PUT,则必须发送资源的完整表示 . 如果您不发送isPaired,服务器应该使其无效 - 在您的情况下,服务器将其设置为默认值 .
如果要使用PATCH,可以省略isPaierd,并且不会更改,但必须找到提交表单的代码,并添加值为true的第二个参数 .
Symfony的\分量\表| FormInterface: