简体   繁体   English

PUT操作将创建新的嵌入式文档,而不是在Api平台上对其进行更新

[英]PUT operation creates new embedded document instead of updating it on Api Platform

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. 就像标题中所述,基于注释的Api Platform PUT操作无法正常完成部分嵌入式文档使用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. 确实,尽管我尝试了所有不同的配置,但我仍未成功更新已在父文档中设置的嵌入式文档。

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. 我尝试更改相关文档中的注释,例如通过更改规范化和非规范化组,尝试不同的嵌入式文档策略,通过为PUT方法设置特定的itemOperations等来进行更改。在此特定问题上的文档相当少,因为它似乎主要是针对SQL编写的使用Doctrine ORM进行操作。

The most "interesting" information I found comes from this chapter in Api Platform documentation : https://api-platform.com/docs/core/serialization/#denormalization 我发现的最“有趣”的信息来自Api Platform文档中的本章: https : //api-platform.com/docs/core/serialization/#denormalization

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. 上面写着“如果嵌入式资源中存在@id密钥,那么将通过数据提供程序检索与给定URI对应的对象。嵌入关系中的任何更改也将应用于该对象。”文档应该被检索,但事实并非如此。

I have a parent document, Page, with an embedded document, Basic, in an embedOne relationship. 我有一个父文档Page和一个嵌入文档Basic处于embedOne关系中。

/**
 * @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;
}

On the other side, I have Basic embedded document : 另一方面,我有Basic嵌入式文档:

/**
 * @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;
}

So when I make a "POST" request on /api/pages such as this one: 因此,当我在诸如此类的/ api / pages上发出“ POST”请求时:

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

I receive this 201 response: 我收到以下201回应:

{
    "@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"
    }
}

But I make a "PUT" request on this resource through api/pages/11 with those parameters: 但是我通过带有这些参数的api / pages / 11在此资源上发出了“ PUT”请求:

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

I receive this 200 response: 我收到以下200条回复:

{
    "@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"
    }
}

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. 如您所见,为PUT操作生成了一个新的Basic嵌入式文档,其中使用了请求中设置的值。 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! 干杯!

I think this is your problem. 我认为这是您的问题。 You need to set the id on embedded Relations otherwise they will be created. 您需要在嵌入的Relations上设置ID,否则将创建它们。

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

From the docs: 从文档:

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.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM