Платформа API - POSTing / PUTing сущности с отношениями

Я установил сервер на основе API-платформы. Я автоматически сгенерировал некоторые Entities с помощью пакета symfony maker-bundle и модифицировал их в соответствии со своими потребностями. Если я вызываю API с помощью POST-запроса, я получаю ошибку Uncaught PHP Exception Symfony\Component\Serializer\Exception\NotNormalizableValueException: "Update is not allowed for this operation.". Насколько я понимаю, таким образом нельзя обновлять связанные сущности. Но я не это имел в виду. Я просто хочу наладить отношения

Что я делаю неправильно?

Ниже приводится упрощенная версия моей проблемы. Я не учел автоматически сгенерированные геттеры / сеттеры.

Сущности:

/**
 * @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."

person MontyBurns    schedule 02.11.2019    source источник


Ответы (2)


Думаю, в этом нет необходимости

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

в вашей Language сущности, потому что это отношение ManyToOne, поэтому, если у сущности Language нет, это не будет иметь значения.

Также добавьте контекст денормализации в свой языковой объект или просто удалите его из обоих объектов.

person Vipulw    schedule 12.11.2019
comment
Не знаю, решает ли ваш ответ мой вопрос? Ошибка все еще присутствует, если я закомментирую упомянутые вами строки. Что я должен добавить для контекста деномализации? Я думал, что моя аннотация обрабатывает нормализацию и денормализацию - person MontyBurns; 17.11.2019

Если я правильно понимаю, вы хотите сделать - обновить существующий язык - и связать его с вновь созданной книгой в той же операции api?

Это, вероятно, действительно не сработает. Вы можете использовать две операции (обновить и назначить через IRI, например "/api/language/234"). Или вы можете создать новую книгу и язык сразу.

В любом случае все языки должны быть созданы заранее, а затем только выбранные из них должны быть назначены для книг - тогда не нужно менять имя во время действия создания новой книги? :-)

person Jan Stefanides    schedule 12.11.2019
comment
Нет, я не хочу менять язык. Я хочу назначить существующий язык для книги - person MontyBurns; 17.11.2019
comment
Чтобы назначить существующий, просто используйте формат "language": "/api/language/234" - достаточно указать id, другие атрибуты языка невозможны, если вы не хотите создать новую строку языка. - person Jan Stefanides; 18.11.2019