使用FOSRestBundle的Symfony表单集合和JSON发布请求

时间:2015-10-29 13:43:39

标签: symfony symfony-forms

我目前有一个表单设置,其中唯一的元素是集合,因此我们可以将商店产品提交到API端点。

我在控制器中实现这个的方式感觉不对,当表单有错误时我对响应不满意。所以我只是想知道这是否是一种更标准化的方法。

示例POST有效负载看起来像这个JSON数组:

[
    {
        "productId": 12,
        "price": 12.99
    },
    {
        "productId": 13,
        "price": 15.99
    }
]

我的FOSRestBundle控制器操作设置如下所示,我正在进行JSON解码并使用表单的products参数构建数组。我不禁觉得必须有更好的办法吗?

/**
 * @Post("/api/store/products")
 * @View
 */
public function postProductsAction(Request $request)
{
    $form = $this->createForm(new ProductsType($this->em));
    $form->submit(['products' => json_decode($request->getContent(), true)]);

    if ($form->isValid()) {
        // save logic
    }

    return $form;
}

我的收藏表格:

class ProductsType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('products', 'collection', [
            'allow_add' => true,
            'allow_delete' => true,
            'by_reference' => false,
            'type' => new ProductType()
        ]);
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults([
            'csrf_protection' => false,
            'cascade_validation' => true
        ]);
    }
}

产品表格类型。

class ProductType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('productId', 'entity', [
                'class' => 'CatalogueBundle:Product',
                'property_path' => 'product'
                // some more unrelated options...
            ])
            ->add('price', 'number');
    }
}

然后是失败的验证JSON响应的问题。看起来像这样:

{
    "code": 400,
    "message": "Validation Failed",
    "errors": {
        "children": {
            "products": {
                "children": [
                    {
                        "children": {
                            "productId": {
                                "errors": [
                                    "You must provide a productId."
                                ]
                            },
                            "price": {}
                        }
                    }
                }
            ]
        }
    }
}

前端团队不会喜欢这种回应!像theres这样的感觉不需要它如此深深地嵌套。

1 个答案:

答案 0 :(得分:0)

1)您需要使用FOSRestBundle的BodyListener。如果设置正确,您应该收到已经解码为数组的请求参数。

fos_rest:
    body_listener:
        decoders:
            json: fos_rest.decoder.json

查看正文监听器的文档:http://symfony.com/doc/current/bundles/FOSRestBundle/3-listener-support.html#body-listener

2)要获得更加用户友好的表单错误,请使用FOSRestBundle规范化程序之一:https://github.com/FriendsOfSymfony/FOSRestBundle/tree/master/Serializer/Normalizer

更多信息:https://symfony.com/doc/current/bundles/FOSRestBundle/2-the-view-layer.html#forms-and-views