我对Symfony很新,并且在实现RESTful API时遇到问题,特别是传入的JSON不包含所有参数的表单。
到目前为止,我设置了一个处理POST请求的控制器。该应用程序POST一个包含isPaired
和/或isTutorialSeen
字段的JSON。
当POST查询包含{"isTutorialSeen":true, "isPaired": true}
时,当我尝试$form->get('isPaired')->getData()
或$form->get('isTutorialSeen')->getData()
时,这两个字段都设置为true。这就是我的期望。
当POST查询包含{"isTutorialSeen":true}
时,我可以看到当我尝试$form->get('isPaired')->getData()
时,表单的isPaired字段设置为false。可能是因为该字段未在JSON中传递。不在JSON中传递它应该具有含义"不要更新它",而不是"将其设置为false"。与HTTP' PATCH'相同语法。
我抓挠我的头发,想弄清楚我怎么能得到一个“无效”的头发。例如,而不是“假”'回到这里。
我的控制器实现如下:
/**
* @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在负责将表单数据(或缺少数据)映射到对象的层中,这不是我需要的。 任何帮助将不胜感激!
答案 0 :(得分:-1)
实体的默认字段值设置如下:
protected $isTutorialSeen = null;
但我不确定在这种情况下是否会有所帮助。
答案 1 :(得分:-1)
当您要创建一个全新的资源时,您使用POST方法。根据设计,POST请求方法请求Web服务器接受并存储请求消息正文中包含的数据。
如果您决定更新资源,则应创建PUT或PATCH请求。 PATCH主要就像PUT一样,除非您不需要发送整个资源主体。
因此,您必须更改的第一件事是 - 使用PUT(或PATCH)进行更新。
如果您要使用PUT,则必须发送资源的完整表示。如果您没有发送isPaired,服务器应该使其无效 - 在您的情况下,服务器会将其设置为默认值。
如果要使用PATCH,可以省略isPaierd,但不能更改,但必须找到提交表单的代码,并添加值为true的第二个参数。
$form->submit($data, true);
的Symfony \元器件\表格| FormInterface:
/**
* Submits data to the form, transforms and validates it.
*
* @param null|string|array $submittedData The submitted data
* @param bool $clearMissing Whether to set fields to NULL
* when they are missing in the
* submitted data.
*
* @return FormInterface The form instance
*
* @throws Exception\AlreadySubmittedException If the form has already been submitted.
*/
public function submit($submittedData, $clearMissing = true);