Платформа API: невозможно использовать тип данных json с MySQL для работы

0

Я новичок в платформе API и пытаюсь получить атрибут данных json, чтобы сохранить MySQL как объект json. Я просмотрел документацию по платформе API и искал ответ, но ничего не нашел на этом.

Моя настройка:

Столбец MySQL определяется как:

'document' json DEFAULT NULL 

Я определил объект PHP MyEntity и атрибут json описывается следующим образом:

/**
 * @var json 
 *
 * @ORM\Column(type="json")
 */
private $document;

/**
 * Get document.
 *
 * @return json
 */
public function getDocument()
{
    return $this->document;
}

/**
 * Set document.
 *
 * @param json $document
 *
 * @return MyEntity
 */
public function setDocument($document)
{
    $this->document = $document;

    return $this;
}

Теперь, когда вверх по этому URL-адресу, который показывает интерфейс по умолчанию для MyEntity и выполняет POST, чтобы создать его с помощью этого json-ld (упрощая, чтобы исключить другие столбцы):

{
    "document": "{"test": "value"}"
}

Я получаю ошибку 400 Bad Request

{
    "@context": "/contexts/Error",
    "@type": "hydra:Error",
    "hydra:title": "An error occurred",
    "hydra:description": "Syntax error",
    "trace": [
    {
        "namespace": "",
        "short_class": "",
        "class": "",
        "type": "",
        "function": "",
        "file": "/Library/WebServer/Documents/test/vendor/symfony/symfony/src/Symfony/Component/Serializer/Encoder/JsonDecode.php",
        "line": 78,
        "args": []
    },
...

Я избежал двойных кавычек (что мне кажется странным, что это вам нужно сделать, поскольку это сам json, который описывает другой объект json) следующим образом:

{
    "document": "{\"test\": \"value\"}"
}

и снова выполните POST:

Я получаю ошибку 400 Bad Request с другой внутренней ошибкой:

{
    "@context": "/contexts/Error",
    "@type": "hydra:Error",
    "hydra:title": "An error occurred",
    "hydra:description": "Could not denormalize object of type AppBundle\\Entity\\json, no supporting normalizer found.",
    "trace": [
    {
        "namespace": "",
        "short_class": "",
        "class": "",
        "type": "",
        "function": "",
        "file": "/Library/WebServer/Documents/test/vendor/symfony/symfony/src/Symfony/Component/Serializer/Serializer.php",
       "line": 295,
       "args": []
    },  
...

Таким образом, похоже, что платформа API не распознает тип данных JSON и ожидает, что пользовательский объект для него... не кажется мне прав.

Я также посмотрел типы для доктрины, которые, как я понимаю, API Platform использует и находит эту информацию:

Некоторые производители имеют собственный тип JSON, и Doctrine будет использовать его, если это возможно, и в противном случае молча откидывается на тип текста поставщиков, чтобы обеспечить наиболее эффективные требования к хранению. Если у поставщика нет родного типа JSON, этот тип требует подсказки для комментария столбца SQL, чтобы он мог быть обратным запросом из базы данных. Doctrine не может правильно отобразить этот тип на продавцах, не поддерживающих комментарии к колонкам, и вместо этого вернется к типу текста.

Но поскольку MySQL поддерживает тип данных JSON, я думал, что это будет просто работать, но, видимо, нет. Любая помощь в отношении того, как API-платформа работает с типом данных JSON с использованием MYSQL, будет высоко оценена.

  • 0
    Знает ли Doctrine о типе данных JSON в MySQL 5.7?
  • 1
    Я погуглил и нашел эту ссылку: github.com/doctrine/dbal/pull/2266 , которая указывает мне, что теперь так и есть.
Теги:
api-platform.com

1 ответ

0
Лучший ответ

Вы получаете эту ошибку из-за подсказок типа PHPdoc. Api-платформа использует метаданные PHPdoc во время нормализации.

В PHP нет таких типов, как "json", поэтому он будет искать класс в том же пространстве имен.

Из документации Doctrine:

Значения, полученные из базы данных, всегда преобразуются в массив PHP или нулевые типы с использованием функции PHP json_decode().

Таким образом, вы должны изменить свой тип PHPDoc typehint на array

/**
 * @var array
 *
 * @ORM\Column(type="json")
 */
private $document;

/**
 * Get document.
 *
 * @return array
 */
public function getDocument()
{
    return $this->document;
}

/**
 * Set document.
 *
 * @param array $document
 *
 * @return MyEntity
 */
public function setDocument($document)
{
    $this->document = $document;

    return $this;
}
  • 0
    Внесение этого изменения сделало свое дело! Теперь я могу хранить свои объекты JSON ... спасибо!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню