php – 如何使用FOSRest和Symfony 3.0正确执行REST API POST调用
作者:互联网
对于我目前正在构建的API,我希望能够使用具有以下内容的JSON正文发送请求
{"title": "foo"}
为名为Project的Entity创建新的数据库记录.
我创建了一个子类FOSRestController的控制器.为了创建一个项目,我做了一个动作
/**
* @Route("/")
*
* @ApiDoc(
* section="Project",
* resource=true,
* input={"class"="AppBundle\Form\API\ProjectType"},
* description="Creates a new project",
* statusCodes={
* 201="Returned when successful",
* }
* )
*
* @Method("POST")
* @Rest\View(statusCode=201)
*/
public function createProjectAction(Request $request)
{
$project = new Project();
$form = $this->createForm(ProjectType::class, $project);
$form->submit(($request->request->get($form->getName())));
if ($form->isSubmitted() && $form->isValid()) {
return $project;
}
return View::create($form, 400);
}
ProjectType看起来像这样
class ProjectType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('title');
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Project'
));
}
}
但是,当我尝试将所述JSON发布到API时,它会响应title属性不能为空,这很好,因为这是为它设置的验证规则.但是,它是设置的.我突然意识到我必须发送以实际对象名称为前缀的JSON才能使其工作:
{"project":{"title": "bla"}}
公平地感觉有点奇怪,它应该足以发布属性.
所以,基于这些信息我只有两个问题:
>为什么我需要使用($request-> request-> get($form-> getName()))“提交”此表单,不应该$request足够吗?
>我需要更改FormType以按原样验证实体,而不是使用实体名称作为前缀?
编辑1:在默认选项中添加或删除data_class根本不会改变行为.
解决方法:
这是因为Symfony Controller“createForm”辅助方法的工作原理.其背后的推理是多个表单可以具有相同的目标URL.通过使用表单名称作为前缀,Symfony可以知道提交了哪个表单.
通过查看“createForm”方法实现可以看出:
public function createForm($type, $data = null, array $options = array())
{
return $this->container->get('form.factory')->create($type, $data, $options);
}
如果您不想要这种行为,那么更改它真的很容易:
public function createProjectAction(Request $request)
{
$project = new Project();
$form = $this->get('form.factory')->createNamed(null, new ProjectType(), $project);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
return $project;
}
return View::create($form, 400);
}
所以你基本上创建了一个“无名”形式.由于您正在构建API,因此在基本控制器中将其拉入createNamelessForm($type,$data,$options)帮助器方法可能是个好主意,这样您就不必显式地从容器中获取Form Factory时间,让眼睛更容易.
评论你的编辑
包装密钥不是由“data_class”选项生成的,而是由表单类型上的“getName()”方法生成的.
标签:php,rest,symfony,fosrestbundle 来源: https://codeday.me/bug/20190519/1135955.html