当前位置:  开发笔记 > 编程语言 > 正文

如何使用FOSRest和Symfony 3.0正确执行REST API POST调用

如何解决《如何使用FOSRest和Symfony3.0正确执行RESTAPIPOST调用》经验,为你挑选了1个好方法。

对于我目前正在构建的API,我希望能够使用具有以下内容的JSON正文发送请求

{"title": "foo"}

为被调用的实体创建新的数据库记录Project.

我做了一个子类控制器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在默认选项中添加或删除不会改变行为.



1> Igor Pantovi..:

这是因为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()"方法生成的.

推荐阅读
mobiledu2402852413
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有