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

查看:29
本文介绍了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 平台文档中的这一章: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;
}

另一方面,我有基本的嵌入文档:

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天全站免登陆