PUT操作将创建新的嵌入式文档,而不是在Api平台上对其进行更新 [英] PUT operation creates new embedded document instead of updating it on Api Platform

查看:76
本文介绍了PUT操作将创建新的嵌入式文档,而不是在Api平台上对其进行更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我陷入了几天无法解决的问题.正如标题中所述,基于注释的Api Platform PUT操作对于使用MongoDB ODM对嵌入式文档进行部分更新而言无法按预期进行.

I am stuck on an issue I cannot solve for few days now. As said in the title, Api Platform PUT operation based on annotations doesn't work as expected with regards to partial update on embedded document with MongoDB ODM.

实际上,尽管我尝试了所有不同的配置,但我没有成功更新已在父文档中设置的嵌入式文档.

Indeed, despite all the different configurations I tried, I didn't succeed in updating an embedded document already set in a parent document.

我试图更改相关文档中的注释,例如通过更改规范化和非规范化组,尝试使用不同的嵌入式文档策略,通过设置PUT方法的特定itemOperations等.使用Doctrine ORM为SQL操作编写的.

I tried to change annotations in relevant documents, for example by changing normalization and denormalization groups, by trying different embedded document strategies, by setting specific itemOperations for PUT method, etc. Documentation is quite poor on this specific issue because it seems mainly made for SQL operations using Doctrine ORM.

我发现的最有趣"的信息来自Api Platform文档中的本章: https://api-platform.com/docs/core/serialization/#denormalization

The most "interesting" information I found comes from this chapter in Api Platform documentation : https://api-platform.com/docs/core/serialization/#denormalization

上面写着如果嵌入式资源中存在@id密钥,则将通过数据提供程序检索与给定URI对应的对象.嵌入式关系中的任何更改也将应用于该对象.",则应检索相应的文档,但不能.

As it is written "If an @id key is present in the embedded resource, then the object corresponding to the given URI will be retrieved through the data provider. Any changes in the embedded relation will also be applied to that object.", corresponding document should be retrieved, but it doesn't.

我有一个父文档Page和一个嵌入文档Basic处于embedOne关系.

I have a parent document, Page, with an embedded document, Basic, in an embedOne relationship.

/**
 * @ApiFilter(SearchFilter::class, properties={"basic.name": "ipartial", "basic.title": "exact"})
 * 
 * @ApiResource(
 *  normalizationContext={"groups"={"read"}},
 *  denormalizationContext={"groups"={"write"}}
 * )
 *
 * @ODM\Document
 */
class Page
{
    /**
     * @ODM\Id(strategy="increment", type="integer")
     */
    private $id;

    /**
     * Embedded document with data shared by all Pages and Modules such as name, title, etc.
     * 
     * @Assert\Valid
     * @Groups({"read", "write"})
     * @ODM\EmbedOne(targetDocument=Basic::class, strategy="set")
     */
    private $basic;
}

另一方面,我有Basic嵌入式文档:

On the other side, I have Basic embedded document :

/**
 * @ApiResource()
 * 
 * @ODM\EmbeddedDocument
 */
class Basic
{
    /**
     * @ApiProperty(identifier=true)
     * @Groups({"read", "write"})
     * @ODM\Id(strategy="INCREMENT", type="integer")
     */
    public $id;

    /**
     * @Groups({"read", "write"})
     * @ODM\Field(type="string")
     */
    private $title;

    /**
     * @Groups({"read", "write"})
     * @ODM\Field(type="string")
     */
    private $name;

    /**
     * @Groups({"read", "write"})
     * @ODM\Field(type="string")
     */
    private $category;
}

因此,当我在/api/pages这样的页面上发出"POST"请求时:

So when I make a "POST" request on /api/pages such as this one:

{
    "basic": {
        "title": "Master",
        "name": "Peter Jackson",
        "category": "Director"
    }
}

我收到以下201条回复:

I receive this 201 response:

{
    "@context": "\/api\/contexts\/Page",
    "@id": "\/api\/pages\/11",
    "@type": "Page",
    "basic": {
        "@id": "\/api\/basics\/21",
        "@type": "Basic",
        "id": 21,
        "title": "Master",
        "name": "Peter Jackson",
        "category": "Director"
    }
}

但是我通过带有这些参数的api/pages/11在此资源上发出了"PUT"请求:

But I make a "PUT" request on this resource through api/pages/11 with those parameters:

{
  "basic": {
    "title": "Master",
    "name": "Steven Spielberg",
    "category": "Director"
  }
}

我收到这200条回复:

I receive this 200 response:

{
    "@context": "\/api\/contexts\/Page",
    "@id": "\/api\/pages\/11",
    "@type": "Page",
    "basic": {
        "@id": "\/api\/basics\/22",
        "@type": "Basic",
        "id": 22,
        "title": "Master",
        "name": "Steven Spielberg",
        "category": "Director"
    }
}

如您所见,为PUT操作生成了一个新的Basic嵌入式文档,其中使用了请求中设置的值.但是我不希望发生这种情况,我想系统地更新所创建的嵌入式文档,因为它已经创建.非常感谢,如果您知道如何处理.干杯!

As you can see a new Basic embedded document is generated for the PUT operation in which the values set in the request are used. But I don't want this to happen, I want to systematically update the embedded document created, since it has been created. Thanks a lot if you know how to deal with this. Cheers!

推荐答案

我认为这是您的问题.您需要在嵌入式关系"上设置ID,否则将创建它们.

I think this is your problem. You need to set the id on embedded Relations otherwise they will be created.

{
  "basic": {
    "@id": "\/api\/basics\/21",
    "title": "Master",
    "name": "Steven Spielberg",
    "category": "Director"
  }
}

从文档中

If an @id key is present in the embedded resource, then the object corresponding to the given URI will be retrieved through the data provider. Any changes in the embedded relation will also be applied to that object.

If no @id key exists, a new object will be created containing data provided in the embedded JSON document.

这篇关于PUT操作将创建新的嵌入式文档,而不是在Api平台上对其进行更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆