API平台-通过关系发布/放置实体

时间:2019-11-02 19:15:37

标签: php symfony api-platform.com

我已基于API-Platform设置了服务器。 我用symfony maker-bundle自动生成了一些实体,并对其进行了修改以满足我的需求。 如果我通过POST请求调用API,则会收到错误Uncaught PHP Exception Symfony\Component\Serializer\Exception\NotNormalizableValueException: "Update is not allowed for this operation."。 据我了解,不允许以这种方式更新相关实体。但这不是我想要的。我只想建立关系

我在做什么错了?

以下是我的问题的简化版本。我省去了自动生成的getter / setter。

实体:

/**
 * @ApiResource(
 *     normalizationContext={"groups"={"book"}},
 *     denormalizationContext={"groups"={"book"}}
 * )
 */
class Book
{
    /**
     * @var integer
     *
     * @Groups({"book"})
     *
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer", options={"unsigned"=true})
     */
     private $id;


    /**
     * @var string
     *
     * @Groups({"book"})
     *
     * @ORM\Column(type="string", length=255, nullable=true)
     */
    private $name;

    /**
     * @var Language
     *
     * @Groups({"book"})
     *
     * @ORM\ManyToOne(targetEntity="App\Entity\Language", inversedBy="books")
     * @ORM\JoinColumn(nullable=false)
     */
    private $language;
}
/**
 * @ApiResource(normalizationContext={"groups"={"language", "book"}})
 */
class Language
{
    /**
     * @var integer
     *
     * @Groups({"language", "book"})
     *
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer", options={"unsigned"=true})
     */
    private $id;

    /**
     * @var string
     *
     * @Groups({"language", "book"})
     *
     * @ORM\Column(type="string", length=255)
     */
    private $name;

    /**
     * @var Book
     *
     * @ORM\OneToMany(targetEntity="App\Entity\Book", mappedBy="language")
     */
    private $books;
}

如果我将以下POST请求发送到API,以创建具有已经存在的语言

的图书
{
    'name': 'some Name',
    'language': {
        'id': 234,
        'name': "some languages name"
    }
}

API响应此错误

Uncaught PHP Exception Symfony\Component\Serializer\Exception\NotNormalizableValueException: "Update is not allowed for this operation."

2 个答案:

答案 0 :(得分:1)

我想不需要

/**
 * @var Book
 *
 * @ORM\OneToMany(targetEntity="App\Entity\Book", mappedBy="language")
 */
private $books;

在您的Language实体中,因为它是ManyToOne关系,所以如果Language实体不具备该关系,那么工作就无关紧要。

还可以向您的语言实体添加非规范化上下文,或者只是将其从两个实体中删除。

答案 1 :(得分:1)

如果我理解正确,您想 -更新现有语言 -并将其关联到新创建的书 在相同的api操作中?

这可能真的行不通。您可以使用两种操作(通过"/api/language/234"等IRI更新和分配)。或者,您可以一次创建新的书籍和语言。

无论如何,应该先创建所有语言,然后才将所选语言分配给“图书”-那么在进行新的“图书创建”操作期间是否不需要更改名称? :-)